tor  master
Data Structures | Macros | Functions
timers.c File Reference

Wrapper around William Ahern's fast hierarchical timer wheel implementation, to tie it in with a libevent backend. More...

#include "orconfig.h"
#include "compat.h"
#include "compat_libevent.h"
#include "timers.h"
#include "torlog.h"
#include "util.h"
#include "src/ext/timeouts/timeout.c"
Include dependency graph for timers.c:

Data Structures

struct  timeout_cb
 

Macros

#define TOR_TIMERS_PRIVATE
 
#define TIMEOUT_PUBLIC   static
 
#define TIMEOUT_DISABLE_INTERVALS
 
#define TIMEOUT_DISABLE_RELATIVE_ACCESS
 
#define TIMEOUT_CB_OVERRIDE
 
#define WHEEL_NUM   5
 
#define USEC_PER_TICK   100
 
#define USEC_PER_SEC   1000000
 
#define MIN_CHECK_SECONDS   3600
 
#define MIN_CHECK_TICKS   (((timeout_t)MIN_CHECK_SECONDS) * (1000000 / USEC_PER_TICK))
 

Functions

STATIC void timers_run_pending (void)
 
void timers_initialize (void)
 
void timers_shutdown (void)
 
tor_timer_ttimer_new (timer_cb_fn_t cb, void *arg)
 
void timer_free_ (tor_timer_t *t)
 
void timer_set_cb (tor_timer_t *t, timer_cb_fn_t cb, void *arg)
 
void timer_get_cb (const tor_timer_t *t, timer_cb_fn_t *cb_out, void **arg_out)
 
void timer_schedule (tor_timer_t *t, const struct timeval *tv)
 
void timer_disable (tor_timer_t *t)
 

Detailed Description

Wrapper around William Ahern's fast hierarchical timer wheel implementation, to tie it in with a libevent backend.

Only use these functions from the main thread.

The main advantage of tor_timer_t over using libevent's timers is that they're way more efficient if we need to have thousands or millions of them. For more information, see http://www.25thandclement.com/~william/projects/timeout.c.html

Periodic timers are available in the backend, but I've turned them off. We can turn them back on if needed.

Macro Definition Documentation

◆ MIN_CHECK_SECONDS

#define MIN_CHECK_SECONDS   3600

Check at least once every N seconds.

◆ MIN_CHECK_TICKS

#define MIN_CHECK_TICKS   (((timeout_t)MIN_CHECK_SECONDS) * (1000000 / USEC_PER_TICK))

Check at least once every N ticks.

◆ USEC_PER_SEC

#define USEC_PER_SEC   1000000

One million microseconds in a second

◆ USEC_PER_TICK

#define USEC_PER_TICK   100

We need to choose this value carefully. Because we're using timer wheels, it actually costs us to have extra resolution we don't use. So for now, I'm going to define our resolution as .1 msec, and hope that's good enough.

Note that two of the most popular libevent backends (epoll without timerfd, and windows select), simply can't support sub-millisecond resolution, do this is optimistic for a lot of users.

Function Documentation

◆ timer_disable()

void timer_disable ( tor_timer_t t)

Cancel the timer t if it is currently scheduled. (It's okay to call this on an unscheduled timer.

◆ timer_free_()

void timer_free_ ( tor_timer_t t)

Release all storage held by t, and unschedule it if was already scheduled.

◆ timer_get_cb()

void timer_get_cb ( const tor_timer_t t,
timer_cb_fn_t *  cb_out,
void **  arg_out 
)

Set *cb_out (if provided) to this timer's callback function, and *arg_out (if provided) to this timer's callback argument.

◆ timer_new()

tor_timer_t* timer_new ( timer_cb_fn_t  cb,
void *  arg 
)

Allocate and return a new timer, with given callback and argument.

◆ timer_schedule()

void timer_schedule ( tor_timer_t t,
const struct timeval tv 
)

Schedule the timer t to fire at the current time plus a delay of delay microseconds. All times are relative to monotime_get().

◆ timer_set_cb()

void timer_set_cb ( tor_timer_t t,
timer_cb_fn_t  cb,
void *  arg 
)

Change the callback and argument associated with a timer t.

◆ timers_initialize()

void timers_initialize ( void  )

Initialize the timers subsystem. Requires that libevent has already been initialized.

◆ timers_run_pending()

STATIC void timers_run_pending ( void  )

Run the callback of every timer that has expired, based on the current output of monotime_get().

Here is the call graph for this function:

◆ timers_shutdown()

void timers_shutdown ( void  )

Release all storage held in the timers subsystem. Does not fire timers.