Example #1
0
/** Initializes the libevent backend for a periodic event. */
void
periodic_event_setup(periodic_event_item_t *event)
{
  if (event->ev) { /* Already setup? This is a bug */
    log_err(LD_BUG, "Initial dispatch should only be done once.");
    tor_assert(0);
  }

  event->ev = tor_event_new(tor_libevent_get_base(),
                            -1, 0,
                            periodic_event_dispatch,
                            event);
  tor_assert(event->ev);
}
Example #2
0
/**
 * Initialize the timers subsystem.  Requires that libevent has already been
 * initialized.
 */
void
timers_initialize(void)
{
  if (BUG(global_timeouts))
    return; // LCOV_EXCL_LINE

  timeout_error_t err;
  global_timeouts = timeouts_open(0, &err);
  if (!global_timeouts) {
    // LCOV_EXCL_START -- this can only fail on malloc failure.
    log_err(LD_BUG, "Unable to open timer backend: %s", strerror(err));
    tor_assert(0);
    // LCOV_EXCL_STOP
  }

  struct event *timer_event;
  timer_event = tor_event_new(tor_libevent_get_base(),
                              -1, 0, libevent_timer_callback, NULL);
  tor_assert(timer_event);
  global_timer_event = timer_event;

  libevent_timer_reschedule();
}
Example #3
0
/** This function sets the file descriptor in the <b>handle</b> as non-blocking
 * and configures the libevent event structure based on the given <b>flags</b>
 * to ensure that <b>callback</b> is called whenever we have events on the
 * given <b>handle</b>. */
STATIC void
process_unix_setup_handle(process_t *process,
                          process_unix_handle_t *handle,
                          short flags,
                          event_callback_fn callback)
{
  tor_assert(process);
  tor_assert(handle);
  tor_assert(callback);

  /* Put our file descriptor into non-blocking mode. */
  if (fcntl(handle->fd, F_SETFL, O_NONBLOCK) < 0) {
    log_warn(LD_PROCESS, "Unable mark Unix handle as non-blocking: %s",
             strerror(errno));
  }

  /* Setup libevent event. */
  handle->event = tor_event_new(tor_libevent_get_base(),
                                handle->fd,
                                flags,
                                callback,
                                process);
}
Example #4
0
/** Create and schedule a new timer that will run every <b>tv</b> in
 * the event loop of <b>base</b>.  When the timer fires, it will
 * run the timer in <b>cb</b> with the user-supplied data in <b>data</b>. */
periodic_timer_t *
periodic_timer_new(struct event_base *base,
                   const struct timeval *tv,
                   void (*cb)(periodic_timer_t *timer, void *data),
                   void *data)
{
  periodic_timer_t *timer;
  tor_assert(base);
  tor_assert(tv);
  tor_assert(cb);
  timer = tor_malloc_zero(sizeof(periodic_timer_t));
  if (!(timer->ev = tor_event_new(base, -1, PERIODIC_FLAGS,
                                  periodic_timer_cb, timer))) {
    tor_free(timer);
    return NULL;
  }
  timer->cb = cb;
  timer->data = data;
#ifndef HAVE_PERIODIC
  memcpy(&timer->tv, tv, sizeof(struct timeval));
#endif
  event_add(timer->ev, (struct timeval *)tv); /*drop const for old libevent*/
  return timer;
}
Example #5
0
File: procmon.c Project: 4ZM/Tor
/** Create a process-termination monitor for the process specifier
 * given in <b>process_spec</b>.  Return a newly allocated
 * tor_process_monitor_t on success; return NULL and store an error
 * message into *<b>msg</b> on failure.  The caller must not free
 * the returned error message.
 *
 * When the monitored process terminates, call
 * <b>cb</b>(<b>cb_arg</b>).
 */
tor_process_monitor_t *
tor_process_monitor_new(struct event_base *base,
                        const char *process_spec,
                        log_domain_mask_t log_domain,
                        tor_procmon_callback_t cb, void *cb_arg,
                        const char **msg)
{
  tor_process_monitor_t *procmon = tor_malloc(sizeof(tor_process_monitor_t));
  struct parsed_process_specifier_t ppspec;

  tor_assert(msg != NULL);
  *msg = NULL;

  if (procmon == NULL) {
    *msg = "out of memory";
    goto err;
  }

  procmon->log_domain = log_domain;

  if (parse_process_specifier(process_spec, &ppspec, msg))
    goto err;

  procmon->pid = ppspec.pid;

#ifdef MS_WINDOWS
  procmon->hproc = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE,
                               FALSE,
                               procmon->pid);

  if (procmon->hproc != NULL) {
    procmon->poll_hproc = 1;
    log_info(procmon->log_domain, "Successfully opened handle to process %d; "
             "monitoring it.",
             (int)(procmon->pid));
  } else {
    /* If we couldn't get a handle to the process, we'll try again the
     * first time we poll. */
    log_info(procmon->log_domain, "Failed to open handle to process %d; will "
             "try again later.",
             (int)(procmon->pid));
  }
#endif

  procmon->cb = cb;
  procmon->cb_arg = cb_arg;

#ifdef PROCMON_POLLS
  procmon->e = tor_event_new(base, -1 /* no FD */, PERIODIC_TIMER_FLAGS,
                             tor_process_monitor_poll_cb, procmon);
  /* Note: If you port this file to plain Libevent 2, check that
   * procmon->e is non-NULL.  We don't need to here because
   * tor_evtimer_new never returns NULL. */

  evtimer_add(procmon->e, &poll_interval_tv);
#else
#error OOPS?
#endif

  return procmon;
 err:
  tor_process_monitor_free(procmon);
  return NULL;
}
Example #6
0
/** Work-alike replacement for evsignal_new() on pre-Libevent-2.0 systems. */
struct event *
tor_evsignal_new(struct event_base * base, int sig,
                 void (*cb)(int, short, void *), void *arg)
{
  return tor_event_new(base, sig, EV_SIGNAL|EV_PERSIST, cb, arg);
}
Example #7
0
/** Work-alike replacement for evtimer_new() on pre-Libevent-2.0 systems. */
struct event *
tor_evtimer_new(struct event_base *base,
                void (*cb)(int, short, void *), void *arg)
{
  return tor_event_new(base, -1, 0, cb, arg);
}
Example #8
0
int
main(int argc, char **argv)
{
  replyqueue_t *rq;
  threadpool_t *tp;
  int i;
  tor_libevent_cfg evcfg;
  struct event *ev;
  uint32_t as_flags = 0;

  for (i = 1; i < argc; ++i) {
    if (!strcmp(argv[i], "-v")) {
      opt_verbose = 1;
    } else if (!strcmp(argv[i], "-T") && i+1<argc) {
      opt_n_threads = atoi(argv[++i]);
    } else if (!strcmp(argv[i], "-N") && i+1<argc) {
      opt_n_items = atoi(argv[++i]);
    } else if (!strcmp(argv[i], "-I") && i+1<argc) {
      opt_n_inflight = atoi(argv[++i]);
    } else if (!strcmp(argv[i], "-L") && i+1<argc) {
      opt_n_lowwater = atoi(argv[++i]);
    } else if (!strcmp(argv[i], "-R") && i+1<argc) {
      opt_ratio_rsa = atoi(argv[++i]);
    } else if (!strcmp(argv[i], "-C") && i+1<argc) {
      opt_n_cancel = atoi(argv[++i]);
    } else if (!strcmp(argv[i], "--no-eventfd2")) {
      as_flags |= ASOCKS_NOEVENTFD2;
    } else if (!strcmp(argv[i], "--no-eventfd")) {
      as_flags |= ASOCKS_NOEVENTFD;
    } else if (!strcmp(argv[i], "--no-pipe2")) {
      as_flags |= ASOCKS_NOPIPE2;
    } else if (!strcmp(argv[i], "--no-pipe")) {
      as_flags |= ASOCKS_NOPIPE;
    } else if (!strcmp(argv[i], "--no-socketpair")) {
      as_flags |= ASOCKS_NOSOCKETPAIR;
    } else if (!strcmp(argv[i], "-h")) {
      help();
      return 0;
    } else {
      help();
      return 1;
    }
  }
  if (opt_n_threads < 1 ||
      opt_n_items < 1 || opt_n_inflight < 1 || opt_n_lowwater < 0 ||
      opt_n_cancel > opt_n_inflight || opt_n_inflight > MAX_INFLIGHT ||
      opt_ratio_rsa < 0) {
    help();
    return 1;
  }

  init_logging(1);
  crypto_global_init(1, NULL, NULL);
  crypto_seed_rng(1);

  rq = replyqueue_new(as_flags);
  tor_assert(rq);
  tp = threadpool_new(opt_n_threads,
                      rq, new_state, free_state, NULL);
  tor_assert(tp);

  crypto_seed_weak_rng(&weak_rng);

  memset(&evcfg, 0, sizeof(evcfg));
  tor_libevent_initialize(&evcfg);

  ev = tor_event_new(tor_libevent_get_base(),
                     replyqueue_get_socket(rq), EV_READ|EV_PERSIST,
                     replysock_readable_cb, tp);

  event_add(ev, NULL);

#ifdef TRACK_RESPONSES
  handled = bitarray_init_zero(opt_n_items);
  received = bitarray_init_zero(opt_n_items);
  tor_mutex_init(&bitmap_mutex);
  handled_len = opt_n_items;
#endif

  for (i = 0; i < opt_n_inflight; ++i) {
    if (! add_work(tp)) {
      puts("Couldn't add work.");
      return 1;
    }
  }

  {
    struct timeval limit = { 30, 0 };
    tor_event_base_loopexit(tor_libevent_get_base(), &limit);
  }

  event_base_loop(tor_libevent_get_base(), 0);

  if (n_sent != opt_n_items || n_received+n_successful_cancel != n_sent) {
    printf("%d vs %d\n", n_sent, opt_n_items);
    printf("%d+%d vs %d\n", n_received, n_successful_cancel, n_sent);
    puts("FAIL");
    return 1;
  } else {
    puts("OK");
    return 0;
  }
}