#ifndef TIMEOUT_H
#define TIMEOUT_H
#include <stdbool.h>
#include <stdio.h>
#include <inttypes.h>
#include "ext/tor_queue.h"
#if !defined TIMEOUT_PUBLIC
#define TIMEOUT_PUBLIC
#endif
#define TIMEOUT_VERSION TIMEOUT_V_REL
#define TIMEOUT_VENDOR "william@25thandClement.com"
#define TIMEOUT_V_REL 0x20160226
#define TIMEOUT_V_ABI 0x20160224
#define TIMEOUT_V_API 0x20160226
TIMEOUT_PUBLIC int timeout_version(void);
TIMEOUT_PUBLIC const char *timeout_vendor(void);
TIMEOUT_PUBLIC int timeout_v_rel(void);
TIMEOUT_PUBLIC int timeout_v_abi(void);
TIMEOUT_PUBLIC int timeout_v_api(void);
#define TIMEOUT_C(n) UINT64_C(n)
#define TIMEOUT_PRIu PRIu64
#define TIMEOUT_PRIx PRIx64
#define TIMEOUT_PRIX PRIX64
#define TIMEOUT_mHZ TIMEOUT_C(1000)
#define TIMEOUT_uHZ TIMEOUT_C(1000000)
#define TIMEOUT_nHZ TIMEOUT_C(1000000000)
typedef uint64_t timeout_t;
#define timeout_error_t int
#ifndef TIMEOUT_CB_OVERRIDE
struct timeout_cb_t {
void (*fn)(void);
void *arg;
};
#endif
#ifndef TIMEOUT_DISABLE_INTERVALS
#define TIMEOUT_INT 0x01
#endif
#define TIMEOUT_ABS 0x02
#define TIMEOUT_INITIALIZER(flags) { (flags) }
#define timeout_setcb(to, fn, arg) do { \
(to)->callback.fn = (fn); \
(to)->callback.arg = (arg); \
} while (0)
struct timeout {
int flags;
timeout_t expires;
struct timeout_list *pending;
TOR_TAILQ_ENTRY(timeout) tqe;
#ifndef TIMEOUT_DISABLE_CALLBACKS
struct timeout_cb_t callback;
#endif
#ifndef TIMEOUT_DISABLE_INTERVALS
timeout_t interval;
#endif
#ifndef TIMEOUT_DISABLE_RELATIVE_ACCESS
struct timeouts *timeouts;
#endif
};
TIMEOUT_PUBLIC struct timeout *timeout_init(struct timeout *, int);
#ifndef TIMEOUT_DISABLE_RELATIVE_ACCESS
TIMEOUT_PUBLIC bool timeout_pending(struct timeout *);
TIMEOUT_PUBLIC bool timeout_expired(struct timeout *);
TIMEOUT_PUBLIC void timeout_del(struct timeout *);
#endif
struct timeouts;
TIMEOUT_PUBLIC struct timeouts *timeouts_open(timeout_t, timeout_error_t *);
TIMEOUT_PUBLIC void timeouts_close(struct timeouts *);
TIMEOUT_PUBLIC timeout_t timeouts_hz(struct timeouts *);
TIMEOUT_PUBLIC void timeouts_update(struct timeouts *, timeout_t);
TIMEOUT_PUBLIC void timeouts_step(struct timeouts *, timeout_t);
TIMEOUT_PUBLIC timeout_t timeouts_get_curtime(struct timeouts *);
TIMEOUT_PUBLIC timeout_t timeouts_timeout(struct timeouts *);
TIMEOUT_PUBLIC void timeouts_add(struct timeouts *, struct timeout *, timeout_t);
TIMEOUT_PUBLIC void timeouts_del(struct timeouts *, struct timeout *);
TIMEOUT_PUBLIC struct timeout *timeouts_get(struct timeouts *);
TIMEOUT_PUBLIC bool timeouts_pending(struct timeouts *);
TIMEOUT_PUBLIC bool timeouts_expired(struct timeouts *);
TIMEOUT_PUBLIC bool timeouts_check(struct timeouts *, FILE *);
#define TIMEOUTS_PENDING 0x10
#define TIMEOUTS_EXPIRED 0x20
#define TIMEOUTS_ALL (TIMEOUTS_PENDING|TIMEOUTS_EXPIRED)
#define TIMEOUTS_CLEAR 0x40
#define TIMEOUTS_IT_INITIALIZER(flags) { (flags), 0, 0, 0, 0 }
#define TIMEOUTS_IT_INIT(cur, _flags) do { \
(cur)->flags = (_flags); \
(cur)->pc = 0; \
} while (0)
struct timeouts_it {
int flags;
unsigned pc, i, j;
struct timeout *to;
};
TIMEOUT_PUBLIC struct timeout *timeouts_next(struct timeouts *, struct timeouts_it *);
#define TIMEOUTS_FOREACH(var, T, flags) \
struct timeouts_it _it = TIMEOUTS_IT_INITIALIZER((flags)); \
while (((var) = timeouts_next((T), &_it)))
#include <math.h>
#define timeouts_f2i(T, f) \
((timeout_t)ceil((f) * timeouts_hz((T))))
#define timeouts_i2f(T, i) \
((double)(i) / timeouts_hz((T)))
#define timeouts_addf(T, to, timeout) \
timeouts_add((T), (to), timeouts_f2i((T), (timeout)))
#endif