Пример #1
0
Файл: timer.c Проект: chrisy/vpp
/* Arrange for function to be called some time,
   roughly equal to dt seconds, in the future. */
void
timer_call (timer_func_t * func, any arg, f64 dt)
{
  timer_callback_t *t;
  sigset_t save;

  /* Install signal handler on first call. */
  static word signal_installed = 0;

  if (!signal_installed)
    {
      struct sigaction sa;

      /* Initialize time_resolution before first call to timer_interrupt */
      time_resolution = 0.75 / (f64) HZ;

      clib_memset (&sa, 0, sizeof (sa));
      sa.sa_handler = timer_interrupt;

      if (sigaction (TIMER_SIGNAL, &sa, 0) < 0)
	clib_panic ("sigaction");

      signal_installed = 1;
    }

  timer_block (&save);

  /* Add new timer. */
  vec_add2 (timers, t, 1);

  t->time = unix_time_now () + dt;
  t->func = func;
  t->arg = arg;

  {
    word reset_timer = vec_len (timers) == 1;

    if (_vec_len (timers) > 1)
      {
	reset_timer += t->time < (t - 1)->time;
	sort_timers (timers);
      }

    if (reset_timer)
      timer_interrupt (TIMER_SIGNAL);
  }

  timer_unblock (&save);
}
Пример #2
0
int main (int argc, char **argv) {
  static char *ifname = NULL; /* Name of interface to attach to */
  fd_set rfds, readers;
  int n, nfds = 0, i;
  int daemonize = 0;

  /* Remember the name of the executable... */
  progname = strrchr(argv[0], '/');
  
  if (progname)
    progname++;
  else
    progname = argv[0];

  /* Use debug output as default */
  debug = 1;

  /* Parse command line: */
  argc--; argv++;
  while(argc) {
    
    if(argv[0][0] == '-') {
      
      switch(argv[0][1]) {
      case 'i':
	if(argv[1] != NULL) {
	  ifname = argv[1];
	  argc--; argv++;
	  break;
	}
	print_usage();
	exit(-1);
      case 'd':
	debug = 0;
	daemonize = 1;
	break;
      case 'l':
	log_to_file = 1;
	break;
      case 'u':
	unidir_hack = 1;
	break;
      case 'g':
	rreq_gratuitous = 1;
	break;
      case 't':
	log_rt_table = 1;
	if(argv[1] != NULL && argv[1][0] != '-') {
	  printf("arg: %d\n", atoi(argv[1]));
	  rt_log_interval = atoi(argv[1])*1000;
	  argc--; argv++;
	}
	break;
      default:
	print_usage();
	exit(-1);
      }
    } else {
      fprintf(stderr, "Unknown option: %s\n", argv[0]);
      print_usage();
      exit(-1);
    }
    argc--; argv++;
  }
  
  /* Check that we are running as root */
  if (geteuid() != 0) {
    fprintf(stderr, "aodvd: must be root\n");
    exit(1);
  }

  /* Detach from terminal */
  if(daemonize) {
    if (fork() != 0) exit(0);
    /* Close stdin, stdout and stderr... */
    close(0);
    close(1);
    close(2);
    setsid();
  }

  /* Initialize data structures and services... */
  host_init(ifname);
  log_init();  
  timer_queue_init();
  rt_table_init();
  packet_input_init();
  aodv_socket_init();
  
  log(LOG_NOTICE, 0,  "INIT: Attaching to interface %s, override with -i <interface>.",this_host->ifname);

  /* Make sure we cleanup at exit... */
  atexit((void *)&cleanup);

  /* Make sure we run at high priority to make up for the user space
     packet processing... */
  /* nice(-5);  */
  
  /* Catch SIGHUP, SIGINT and SIGTERM type signals */
  signal(SIGHUP, signal_handler);
  signal(SIGINT, signal_handler);
  signal(SIGTERM, signal_handler);

  /* Only capture segmentation faults when we are not debugging... */
#ifndef DEBUG
  signal(SIGSEGV, signal_handler);
#endif
  /* Set sockets to watch... */
  FD_ZERO(&readers);
  for (i = 0; i < nr_callbacks; i++) {
    FD_SET(callbacks[i].fd, &readers);
    if (callbacks[i].fd >= nfds)
      nfds = callbacks[i].fd + 1;
  }
  
  /* Set bcast_time, which ensures that we don't send unnecessary hello
     msgs. */
  this_host->bcast_time = get_currtime();
 
  /* Schedule the first Hello */
  timer_new(HELLO_INTERVAL, hello_send, NULL);
  
  if(log_rt_table)
    timer_new(rt_log_interval, print_rt_table, NULL);

  while(1) {
    memcpy((char *)&rfds, (char *)&readers, sizeof(rfds));
   
    if ((n = select(nfds, &rfds, NULL, NULL, NULL)) < 0) {
      if (errno != EINTR) 
	log(LOG_WARNING, errno, "main.c: Failed select (main loop)");
      continue;
    }

    if (n > 0) {
      for (i = 0; i < nr_callbacks; i++) {
	if (FD_ISSET(callbacks[i].fd, &rfds)) {
	  /* We don't want any timer SIGALRM's while executing the
             callback functions, therefore we block the timer... */
	  timer_block(); 
	  (*callbacks[i].func)(callbacks[i].fd);
	  timer_unblock();
	}
      }
    }
  } /* Main loop */
  return 0;
}