} detail_entry_state_t;
typedef struct listen_detail_t {
- fr_event_t *ev; /* has to be first entry (ugh) */
+ fr_event_timer_t *ev; /* has to be first entry (ugh) */
char const *name; //!< Identifier used in log messages
int delay_time;
char const *filename;
#endif
typedef struct fr_event_list_t fr_event_list_t;
-typedef struct fr_event_t fr_event_t;
+typedef struct fr_event_timer_t fr_event_timer_t;
typedef void (*fr_event_callback_t)(void *, struct timeval *now);
typedef void (*fr_event_status_t)(struct timeval *);
typedef void (*fr_event_fd_handler_t)(fr_event_list_t *el, int sock, void *ctx);
-fr_event_list_t *fr_event_list_init(TALLOC_CTX *ctx, fr_event_status_t status);
+int fr_event_list_num_fds(fr_event_list_t *el);
+int fr_event_list_num_elements(fr_event_list_t *el);
-int fr_event_list_num_fds(fr_event_list_t *el);
-int fr_event_list_num_elements(fr_event_list_t *el);
+int fr_event_timer_delete(fr_event_list_t *el, fr_event_timer_t **parent);
+int fr_event_timer_insert(fr_event_list_t *el,
+ fr_event_callback_t callback,
+ void *ctx, struct timeval *when, fr_event_timer_t **parent);
-int fr_event_insert(fr_event_list_t *el,
- fr_event_callback_t callback,
- void *ctx, struct timeval *when, fr_event_t **parent);
-int fr_event_delete(fr_event_list_t *el, fr_event_t **parent);
+int fr_event_fd_insert(fr_event_list_t *el, int fd,
+ fr_event_fd_handler_t read, fr_event_fd_handler_t write, fr_event_fd_handler_t error,
+ void *ctx);
+int fr_event_fd_delete(fr_event_list_t *el, int fd);
-int fr_event_run(fr_event_list_t *el, struct timeval *when);
+int fr_event_timer_run(fr_event_list_t *el, struct timeval *when);
-int fr_event_now(fr_event_list_t *el, struct timeval *when);
+int fr_event_list_time(struct timeval *when, fr_event_list_t *el);
+int fr_event_corral(fr_event_list_t *el, bool wait);
+void fr_event_service(fr_event_list_t *el);
-int fr_event_fd_insert(fr_event_list_t *el, int fd, fr_event_fd_handler_t handler, fr_event_fd_handler_t write,
- fr_event_fd_handler_t error, void *ctx);
+void fr_event_loop_exit(fr_event_list_t *el, int code);
+bool fr_event_loop_exiting(fr_event_list_t *el);
+int fr_event_loop(fr_event_list_t *el);
-int fr_event_fd_delete(fr_event_list_t *el, int fd);
-
-int fr_event_check(fr_event_list_t *el, bool wait);
-int fr_event_service(fr_event_list_t *el);
-int fr_event_loop(fr_event_list_t *el);
-void fr_event_loop_exit(fr_event_list_t *el, int code);
-bool fr_event_loop_exiting(fr_event_list_t *el);
+fr_event_list_t *fr_event_list_init(TALLOC_CTX *ctx, fr_event_status_t status);
#ifdef __cplusplus
}
* Events associated with this listener
*/
struct timeval when;
- fr_event_t *ev;
+ fr_event_timer_t *ev;
CONF_SECTION const *cs;
void *data;
#endif
struct timeval response_delay; //!< How long to wait before sending Access-Rejects.
- fr_event_t *ev; //!< Event in event loop tied to this request.
+ fr_event_timer_t *ev; //!< Event in event loop tied to this request.
int delay; //!< incrementing delay for various timers
int heap_id; //!< entry in the queue / heap of incoming packets
*/
typedef struct rs_request {
uint64_t id; //!< Monotonically increasing packet counter.
- fr_event_t *event; //!< Event created when we received the original request.
+ fr_event_timer_t *event; //!< Event created when we received the original request.
bool logged; //!< Whether any messages regarding this request were logged.
char const *secret;
- fr_event_t *ev;
+ fr_event_timer_t *ev;
struct timeval when;
struct timeval response_window;
* @file lib/event.c
* @brief Non-thread-safe event handling, specific to a RADIUS server.
*
- * @copyright 2007 The FreeRADIUS server project
- * @copyright 2007 Alan DeKok <aland@ox.org>
+ * @note By non-thread-safe we mean multiple threads can't insert/delete events concurrently
+ * without synchronization.
+ *
+ * @copyright 2007-2016 The FreeRADIUS server project
+ * @copyright 2016 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+ * @copyright 2007 Alan DeKok <aland@ox.org>
*/
RCSID("$Id$")
/** A timer event
*
*/
-struct fr_event_t {
- int heap; //!< Where to store opaque heap data.
-
+struct fr_event_timer_t {
fr_event_callback_t callback; //!< Callback to execute when the timer fires.
void *ctx; //!< Context pointer to pass to the callback.
struct timeval when; //!< When this timer should fire.
- fr_event_t **parent; //!< Prev in linked list.
+ fr_event_timer_t **parent; //!< Previous timer.
+ int heap; //!< Where to store opaque heap data.
};
/** A file descriptor event
static int fr_event_cmp_time_t(void const *a, void const *b)
{
#ifndef NDEBUG
- fr_event_t const *ev_a = talloc_get_type_abort(a, fr_event_t);
- fr_event_t const *ev_b = talloc_get_type_abort(b, fr_event_t);
+ fr_event_timer_t const *ev_a = talloc_get_type_abort(a, fr_event_timer_t);
+ fr_event_timer_t const *ev_b = talloc_get_type_abort(b, fr_event_timer_t);
#else
- fr_event_t const *ev_a = a;
- fr_event_t const *ev_b = b;
+ fr_event_timer_t const *ev_a = a;
+ fr_event_timer_t const *ev_b = b;
#endif
if (ev_a->when.tv_sec < ev_b->when.tv_sec) return -1;
return 0;
}
-static int _event_list_free(fr_event_list_t *list)
-{
- fr_event_list_t *el = list;
- fr_event_t *ev;
-
- while ((ev = fr_heap_peek(el->times)) != NULL) {
- fr_event_delete(el, &ev);
- }
-
- fr_heap_delete(el->times);
-
- close(el->kq);
-
- return 0;
-}
-
-/** Initialise a new event list
+/** Return the number of file descriptors registered with this event loop
*
- * @param[in] ctx to allocate memory in.
- * @param[in] status callback, called on each iteration of the event list.
- * @return
- * - A pointer to a new event list on success (free with talloc_free).
- * - NULL on error.
*/
-fr_event_list_t *fr_event_list_init(TALLOC_CTX *ctx, fr_event_status_t status)
-{
- int i;
- fr_event_list_t *el;
-
- el = talloc_zero(ctx, fr_event_list_t);
- if (!fr_cond_assert(el)) {
- return NULL;
- }
- talloc_set_destructor(el, _event_list_free);
-
- el->times = fr_heap_create(fr_event_cmp_time_t, offsetof(fr_event_t, heap));
- if (!el->times) {
- talloc_free(el);
- return NULL;
- }
-
- for (i = 0; i < FR_EV_MAX_FDS; i++) {
- el->readers[i].fd = -1;
- }
-
- el->kq = kqueue();
- if (el->kq < 0) {
- talloc_free(el);
- return NULL;
- }
-
- el->status = status;
-
- return el;
-}
-
int fr_event_list_num_fds(fr_event_list_t *el)
{
if (!el) return -1;
return el->num_readers;
}
+/** Return the number of timer events currently scheduled
+ *
+ * @param[in] el to return timer events for.
+ * @return number of timer events.
+ */
int fr_event_list_num_elements(fr_event_list_t *el)
{
if (!el) return -1;
return fr_heap_num_elements(el->times);
}
-
-int fr_event_delete(fr_event_list_t *el, fr_event_t **parent)
+/** Delete a timer event from the event list
+ *
+ * @param[in] el to delete event from.
+ * @param[in] parent of the event being deleted.
+ */
+int fr_event_timer_delete(fr_event_list_t *el, fr_event_timer_t **parent)
{
int ret;
- fr_event_t *ev;
+ fr_event_timer_t *ev;
if (!el || !parent || !*parent) return -1;
/*
* Validate the event_t struct to detect memory issues early.
*/
- ev = talloc_get_type_abort(*parent, fr_event_t);
+ ev = talloc_get_type_abort(*parent, fr_event_timer_t);
#else
ev = *parent;
* - 0 on success.
* - -1 on failure.
*/
-int fr_event_insert(fr_event_list_t *el, fr_event_callback_t callback, void *ctx, struct timeval *when,
- fr_event_t **parent)
+int fr_event_timer_insert(fr_event_list_t *el, fr_event_callback_t callback, void *ctx,
+ struct timeval *when, fr_event_timer_t **parent)
{
- fr_event_t *ev;
+ fr_event_timer_t *ev;
if (!el) {
- fr_strerror_printf("Invalid arguments (NULL event list)");
+ fr_strerror_printf("Invalid arguments: NULL event list");
return -1;
}
if (!callback) {
- fr_strerror_printf("Invalid arguments (NULL callback)");
+ fr_strerror_printf("Invalid arguments: NULL callback");
return -1;
}
if (!when || (when->tv_usec >= USEC)) {
- fr_strerror_printf("Invalid arguments (time)");
+ fr_strerror_printf("Invalid arguments: time");
return -1;
}
if (!parent) {
- fr_strerror_printf("Invalid arguments (NULL parent)");
+ fr_strerror_printf("Invalid arguments: NULL parent");
return -1;
}
int ret;
#ifndef NDEBUG
- ev = talloc_get_type_abort(*parent, fr_event_t);
+ ev = talloc_get_type_abort(*parent, fr_event_timer_t);
#else
ev = *parent;
#endif
memset(ev, 0, sizeof(*ev));
} else {
- ev = talloc_zero(el, fr_event_t);
+ ev = talloc_zero(el, fr_event_timer_t);
if (!ev) return -1;
}
}
*parent = ev;
+
return 0;
}
-
-int fr_event_run(fr_event_list_t *el, struct timeval *when)
+/** Remove a file descriptor from the event loop
+ *
+ * @param[in] el to remove file descriptor from.
+ * @param[in] fd to remove.
+ * @return
+ * - 0 if file descriptor was removed.
+ * - <0 on error.
+ */
+int fr_event_fd_delete(fr_event_list_t *el, int fd)
{
- fr_event_callback_t callback;
- void *ctx;
- fr_event_t *ev;
-
- if (!el) return 0;
-
- if (fr_heap_num_elements(el->times) == 0) {
- when->tv_sec = 0;
- when->tv_usec = 0;
- return 0;
- }
-
- ev = fr_heap_peek(el->times);
- if (!ev) {
- when->tv_sec = 0;
- when->tv_usec = 0;
- return 0;
- }
+ int i;
- /*
- * See if it's time to do this one.
- */
- if ((ev->when.tv_sec > when->tv_sec) ||
- ((ev->when.tv_sec == when->tv_sec) &&
- (ev->when.tv_usec > when->tv_usec))) {
- *when = ev->when;
- return 0;
- }
+ if (!el || (fd < 0)) return -1;
- callback = ev->callback;
- ctx = ev->ctx;
+ for (i = 0; i < FR_EV_MAX_FDS; i++) {
+ int j;
+ struct kevent evset;
- /*
- * Delete the event before calling it.
- */
- fr_event_delete(el, ev->parent);
+ j = (i + fd) & (FR_EV_MAX_FDS - 1);
- callback(ctx, when);
- return 1;
-}
+ if (el->readers[j].fd != fd) continue;
+ /*
+ * Tell the kernel to delete it from the list.
+ *
+ * The caller MAY have closed it, in which case
+ * the kernel has removed it from the list. So
+ * we ignore the return code from kevent().
+ */
+ EV_SET(&evset, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
+ (void) kevent(el->kq, &evset, 1, NULL, 0, NULL);
-int fr_event_now(fr_event_list_t *el, struct timeval *when)
-{
- if (!when) return 0;
+ el->readers[j].fd = -1;
+ el->num_readers--;
- if (el && el->dispatch) {
- *when = el->now;
- } else {
- gettimeofday(when, NULL);
+ return 0;
}
- return 1;
+
+ return -1;
}
/** Associate a callback with an FD
return 0;
}
-int fr_event_fd_delete(fr_event_list_t *el, int fd)
+/** Run a single scheduled timer event
+ *
+ * @param[in] el containing the timer events.
+ * @param[in] when Process events scheduled to run before or at this time.
+ * @return
+ * - 0 no timer events fired.
+ * - 1 a timer event fired.
+ */
+int fr_event_timer_run(fr_event_list_t *el, struct timeval *when)
{
- int i;
-
- if (!el || (fd < 0)) return -1;
-
- for (i = 0; i < FR_EV_MAX_FDS; i++) {
- int j;
- struct kevent evset;
-
- j = (i + fd) & (FR_EV_MAX_FDS - 1);
-
- if (el->readers[j].fd != fd) continue;
+ fr_event_callback_t callback;
+ void *ctx;
+ fr_event_timer_t *ev;
- /*
- * Tell the kernel to delete it from the list.
- *
- * The caller MAY have closed it, in which case
- * the kernel has removed it from the list. So
- * we ignore the return code from kevent().
- */
- EV_SET(&evset, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
- (void) kevent(el->kq, &evset, 1, NULL, 0, NULL);
+ if (!el) return 0;
- el->readers[j].fd = -1;
- el->num_readers--;
+ if (fr_heap_num_elements(el->times) == 0) {
+ when->tv_sec = 0;
+ when->tv_usec = 0;
+ return 0;
+ }
+ ev = fr_heap_peek(el->times);
+ if (!ev) {
+ when->tv_sec = 0;
+ when->tv_usec = 0;
return 0;
}
+ /*
+ * See if it's time to do this one.
+ */
+ if ((ev->when.tv_sec > when->tv_sec) ||
+ ((ev->when.tv_sec == when->tv_sec) &&
+ (ev->when.tv_usec > when->tv_usec))) {
+ *when = ev->when;
+ return 0;
+ }
- return -1;
-}
+ callback = ev->callback;
+ ctx = ev->ctx;
+ /*
+ * Delete the event before calling it.
+ */
+ fr_event_timer_delete(el, ev->parent);
-void fr_event_loop_exit(fr_event_list_t *el, int code)
-{
- if (!el) return;
+ callback(ctx, when);
- el->exit = code;
+ return 1;
}
-bool fr_event_loop_exiting(fr_event_list_t *el)
+/** Get the current time according to the event list
+ *
+ * If the event list is currently dispatching events, we return the time
+ * this iteration of the event list started.
+ *
+ * If the event list is not currently dispatching events, we return the
+ * current system time.
+ *
+ * @param[out] when Where to write the time we extracted/acquired.
+ * @param[in] el to get time from.
+ * @return
+ * - 0 on success.
+ * - -1 on error.
+ */
+int fr_event_list_time(struct timeval *when, fr_event_list_t *el)
{
- return (el->exit != 0);
+ if (!when) return -1;
+
+ if (el && el->dispatch) {
+ *when = el->now;
+ } else {
+ gettimeofday(when, NULL);
+ }
+
+ return 1;
}
-int fr_event_check(fr_event_list_t *el, bool wait)
+/** Gather outstanding timer and file descriptor events
+ *
+ * @param[in] el to process events for.
+ * @param[in] wait if true, block on the kevent() call until a timer or file descriptor event occurs.
+ * @return the number of outstanding events.
+ */
+int fr_event_corral(fr_event_list_t *el, bool wait)
{
struct timeval when, *wake;
struct timespec ts_when, *ts_wake;
*/
when.tv_sec = 0;
when.tv_usec = 0;
+ wake = &when;
if (wait) {
if (fr_heap_num_elements(el->times) > 0) {
- fr_event_t *ev;
+ fr_event_timer_t *ev;
ev = fr_heap_peek(el->times);
- if (!ev) {
- fr_exit_now(42);
- }
+ if (!fr_cond_assert(ev)) return -1;
gettimeofday(&el->now, NULL);
- if (fr_timeval_cmp(&el->now, &ev->when) < 0) {
- when = ev->when;
- when.tv_sec -= el->now.tv_sec;
-
- if (when.tv_sec > 0) {
- when.tv_sec--;
- when.tv_usec += USEC;
- } else {
- when.tv_sec = 0;
- }
- when.tv_usec -= el->now.tv_usec;
- if (when.tv_usec >= USEC) {
- when.tv_usec -= USEC;
- when.tv_sec++;
- }
- } else { /* we've passed the event time */
- when.tv_sec = 0;
- when.tv_usec = 0;
- }
-
- wake = &when;
+ /*
+ * Next event is in the future, get the time
+ * between now and that event.
+ */
+ if (fr_timeval_cmp(&ev->when, &el->now) > 0) fr_timeval_subtract(&when, &ev->when, &el->now);
} else {
wake = NULL;
}
-
- } else { /* not waiting, use timeout of zero */
- wake = &when;
}
/*
- * Tell someone what the status is.
+ * Run the status callback
*/
if (el->status) el->status(wake);
ts_wake = NULL;
}
+ /*
+ * Populate el->events with the list of I/O events
+ * that occurred since this function was last occurred
+ * or wait for the next timer event.
+ */
el->num_events = kevent(el->kq, NULL, 0, el->events, FR_EV_MAX_FDS, ts_wake);
/*
* Interrupt is different from timeout / FD events.
*/
- if ((el->num_events < 0) && (errno == EINTR)) {
- el->num_events = 0;
- return 0;
- }
+ if ((el->num_events < 0) && (errno == EINTR)) el->num_events = 0;
- return 1;
+ return el->num_events;
}
-int fr_event_service(fr_event_list_t *el)
+/** Service any outstanding timer or file descriptor events
+ *
+ * @param[in] el containing events to service.
+ */
+void fr_event_service(fr_event_list_t *el)
{
int i;
do {
gettimeofday(&el->now, NULL);
when = el->now;
- } while (fr_event_run(el, &when) == 1);
+ } while (fr_event_timer_run(el, &when) == 1);
}
+}
- return 0;
+/** Signal an event loop exit with the specified code
+ *
+ * The event loop will complete its current iteration, and then exit with the specified code.
+ *
+ * @param[in] el to signal to exit.
+ * @param[in] code for #fr_event_loop to return.
+ */
+void fr_event_loop_exit(fr_event_list_t *el, int code)
+{
+ if (!el) return;
+
+ el->exit = code;
+}
+
+/** Check to see whether the event loop is in the process of exiting
+ *
+ * @param[in] el to check.
+ */
+bool fr_event_loop_exiting(fr_event_list_t *el)
+{
+ return (el->exit != 0);
}
+/** Run an event loop
+ *
+ * @note Will not return until #fr_event_loop_exit is called.
+ *
+ * @param[in] el to start processing.
+ */
int fr_event_loop(fr_event_list_t *el)
{
el->exit = 0;
el->dispatch = true;
while (!el->exit) {
- if (fr_event_check(el, true) < 0) break;
+ if (fr_event_corral(el, true) < 0) break;
- (void) fr_event_service(el);
+ fr_event_service(el);
}
el->dispatch = false;
return el->exit;
}
+/** Cleanup an event list
+ *
+ * Frees/destroys any resources associated with an event list
+ *
+ * @param[in] el to free resources for.
+ */
+static int _event_list_free(fr_event_list_t *el)
+{
+ fr_event_timer_t *ev;
+
+ while ((ev = fr_heap_peek(el->times)) != NULL) {
+ fr_event_timer_delete(el, &ev);
+ }
+
+ fr_heap_delete(el->times);
+
+ close(el->kq);
+
+ return 0;
+}
+
+/** Initialise a new event list
+ *
+ * @param[in] ctx to allocate memory in.
+ * @param[in] status callback, called on each iteration of the event list.
+ * @return
+ * - A pointer to a new event list on success (free with talloc_free).
+ * - NULL on error.
+ */
+fr_event_list_t *fr_event_list_init(TALLOC_CTX *ctx, fr_event_status_t status)
+{
+ int i;
+ fr_event_list_t *el;
+
+ el = talloc_zero(ctx, fr_event_list_t);
+ if (!fr_cond_assert(el)) {
+ return NULL;
+ }
+ talloc_set_destructor(el, _event_list_free);
+
+ el->times = fr_heap_create(fr_event_cmp_time_t, offsetof(fr_event_timer_t, heap));
+ if (!el->times) {
+ talloc_free(el);
+ return NULL;
+ }
+
+ for (i = 0; i < FR_EV_MAX_FDS; i++) {
+ el->readers[i].fd = -1;
+ }
+
+ el->kq = kqueue();
+ if (el->kq < 0) {
+ talloc_free(el);
+ return NULL;
+ }
+
+ el->status = status;
+
+ return el;
+}
#ifdef TESTING
array[i].tv_usec -= 1000000;
array[i].tv_sec++;
}
- fr_event_insert(el, print_time, &array[i], &array[i]);
+ fr_event_timer_insert(el, print_time, &array[i], &array[i]);
}
while (fr_event_list_num_elements(el)) {
gettimeofday(&now, NULL);
when = now;
- if (!fr_event_run(el, &when)) {
+ if (!fr_event_timer_run(el, &when)) {
int delay = (when.tv_sec - now.tv_sec) * 1000000;
delay += when.tv_usec;
delay -= now.tv_usec;
return rcode;
}
-/** Wrap an #fr_event_t providing data needed for unlang events
+/** Wrap an #fr_event_timer_t providing data needed for unlang events
*
*/
typedef struct unlang_event_t {
fr_unlang_fd_callback_t fd_callback; //!< Function to call when FD is readable.
void *inst; //!< Module instance to pass to callbacks.
void *ctx; //!< ctx data to pass to callbacks.
- fr_event_t *ev; //!< Event in this worker's event heap.
+ fr_event_timer_t *ev; //!< Event in this worker's event heap.
} unlang_event_t;
static int _unlang_event_free(unlang_event_t *ev)
{
if (ev->ev) {
- (void) fr_event_delete(ev->request->el, &(ev->ev));
+ (void) fr_event_timer_delete(ev->request->el, &(ev->ev));
return 0;
}
ev->inst = inst;
ev->ctx = ctx;
- if (fr_event_insert(request->el, unlang_event_timeout_handler, ev, when, &(ev->ev)) < 0) {
+ if (fr_event_timer_insert(request->el, unlang_event_timeout_handler, ev, when, &(ev->ev)) < 0) {
REDEBUG("Failed inserting event: %s", fr_strerror());
talloc_free(ev);
return -1;
RDEBUG2("Waiting for %d.%06d seconds",
(int) delay->tv_sec, (int) delay->tv_usec);
- if (fr_event_insert(request->el, unlang_timer_hook, request, &when, &request->ev) < 0) {
+ if (fr_event_timer_insert(request->el, unlang_timer_hook, request, &when, &request->ev) < 0) {
RDEBUG("Failed inserting delay event: %s", fr_strerror());
return -1;
}
static inline void state_machine_timer(char const *file, int line, REQUEST *request,
struct timeval *when)
{
- if (fr_event_insert(el, request_timer, request, when, &request->ev) < 0) {
+ if (fr_event_timer_insert(el, request_timer, request, when, &request->ev) < 0) {
radlog_fatal("%s[%u]: Failed to insert event: %s", file, line, fr_strerror());
}
}
#define USEC (1000000)
#define INSERT_EVENT(_function, _ctx) \
- if (fr_event_insert(el, _function, _ctx, &((_ctx)->when), &((_ctx)->ev)) < 0) { \
+ if (fr_event_timer_insert(el, _function, _ctx, &((_ctx)->when), &((_ctx)->ev)) < 0) { \
radlog_fatal("%s[%u]: %s", __FILE__, __LINE__, fr_strerror()); \
}
#endif
if (request->el) {
- fr_event_delete(request->el, &request->ev);
+ fr_event_timer_delete(request->el, &request->ev);
} else {
- fr_event_delete(el, &request->ev);
+ fr_event_timer_delete(el, &request->ev);
}
/*
/*
* The request is still running. Enforce max_request_time.
*/
- fr_event_now(el, &now);
+ fr_event_list_time(&now, el);
when = request->packet->timestamp;
when.tv_sec += request->root->max_request_time;
#endif
case FR_ACTION_TIMER:
- fr_event_now(el, &now);
+ fr_event_list_time(&now, el);
rad_assert(request->root->cleanup_delay > 0);
#endif
case FR_ACTION_TIMER:
- fr_event_now(el, &now);
+ fr_event_list_time(&now, el);
/*
* See if it's time to send the reply. If not,
if (listener->status != RAD_LISTEN_STATUS_KNOWN) return;
- fr_event_now(el, now);
+ fr_event_list_time(now, el);
switch (listener->type) {
#ifdef WITH_PROXY
}
#endif
- fr_event_now(el, &now);
+ fr_event_list_time(&now, el);
when = request->proxy->packet->timestamp;
#ifdef WITH_COA
/*
* Remove the request from any hashes
*/
- fr_event_delete(el, &request->ev);
+ fr_event_timer_delete(el, &request->ev);
remove_from_proxy_hash(request);
/*
home->num_received_pings = 0;
gettimeofday(&home->revive_time, NULL);
- fr_event_delete(el, &home->ev);
+ fr_event_timer_delete(el, &home->ev);
RPROXY("Marking home server %s port %d alive",
inet_ntop(request->proxy->packet->dst_ipaddr.af,
home->zombie_period_start.tv_sec = start;
home->zombie_period_start.tv_usec = USEC / 2;
- fr_event_delete(el, &home->ev);
+ fr_event_timer_delete(el, &home->ev);
home->num_sent_pings = 0;
home->num_received_pings = 0;
* Delete any outstanding events.
*/
ASSERT_MASTER;
- fr_event_delete(el, &home->ev);
+ fr_event_timer_delete(el, &home->ev);
PROXY("Marking home server %s port %d alive again... we have no idea if it really is alive or not.",
inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr, buffer, sizeof(buffer)),
rad_assert(request->packet->code != PW_CODE_STATUS_SERVER);
rad_assert(request->proxy->home_server != NULL);
- fr_event_now(el, &now);
+ fr_event_list_time(&now, el);
switch (action) {
case FR_ACTION_DUP:
return false;
}
- fr_event_now(el, &now);
+ fr_event_list_time(&now, el);
if (request->delay == 0) {
/*
if (this->status == RAD_LISTEN_STATUS_REMOVE_NOW) {
if (this->count > 0) goto keep_waiting;
- fr_event_delete(el, &this->ev);
+ fr_event_timer_delete(el, &this->ev);
this->print(this, buffer, sizeof(buffer));
DEBUG("... cleaning up socket %s", buffer);
DEBUG("Emitting systemd watchdog notification");
sd_notify(0, "WATCHDOG=1");
- fr_event_now(el, &when);
+ fr_event_list_time(&when, el);
tv_add(&when, sd_watchdog_interval / 2);
- if (!fr_event_insert(el, (fr_event_callback_t) sd_watchdog_event, ctx, &when, ctx)) {
+ if (!fr_event_timer_insert(el, (fr_event_callback_t) sd_watchdog_event, ctx, &when, ctx)) {
rad_panic("Failed to insert watchdog event");
}
}
#endif
request->in_request_hash = false;
- fr_event_delete(el, &request->ev);
+ fr_event_timer_delete(el, &request->ev);
if (main_config.talloc_memory_report) {
RDEBUG2("Cleaning up request packet ID %u with timestamp +%d",
}
{
- static fr_event_t *event;
+ static fr_event_timer_t *event;
now->tv_sec += conf->stats.interval;
now->tv_usec = 0;
- if (fr_event_insert(this->list, rs_stats_process, ctx, now, &event) < 0) {
+ if (fr_event_timer_insert(this->list, rs_stats_process, ctx, now, &event) < 0) {
ERROR("Failed inserting stats interval event");
}
}
static int rs_install_stats_processor(rs_stats_t *stats, fr_event_list_t *el,
fr_pcap_t *in, struct timeval *now, bool live)
{
- static fr_event_t *event;
+ static fr_event_timer_t *event;
static rs_update_t update;
memset(&update, 0, sizeof(update));
rs_tv_add_ms(now, conf->stats.timeout, &(stats->quiet));
}
- if (fr_event_insert(events, rs_stats_process, (void *) &update, now, &event) < 0) {
+ if (fr_event_timer_insert(events, rs_stats_process, (void *) &update, now, &event) < 0) {
ERROR("Failed inserting stats event");
return -1;
}
}
if (request->event) {
- ret = fr_event_delete(events, &request->event);
+ ret = fr_event_timer_delete(events, &request->event);
RS_ASSERT(ret);
}
original->rt_rsp++;
fr_radius_free(&original->linked);
- fr_event_delete(event->list, &original->event);
+ fr_event_timer_delete(event->list, &original->event);
/*
* ...nope it's the first response to a request.
*/
*/
original->linked = talloc_steal(original, current);
rs_tv_add_ms(&header->ts, conf->stats.timeout, &original->when);
- if (fr_event_insert(event->list, _rs_event, original, &original->when, &original->event) < 0) {
+ if (fr_event_timer_insert(event->list, _rs_event, original, &original->when, &original->event) < 0) {
REDEBUG("Failed inserting new event");
/*
* Delete the original request/event, it's no longer valid
original->expect = talloc_steal(original, search.expect);
/* Disarm the timer for the cleanup event for the original request */
- fr_event_delete(event->list, &original->event);
+ fr_event_timer_delete(event->list, &original->event);
/*
* ...nope it's a new request.
*/
*/
original->packet->timestamp = header->ts;
rs_tv_add_ms(&header->ts, conf->stats.timeout, &original->when);
- if (fr_event_insert(event->list, _rs_event, original,
+ if (fr_event_timer_insert(event->list, _rs_event, original,
&original->when, &original->event) < 0) {
REDEBUG("Failed inserting new event");
do {
now = header->ts;
- } while (fr_event_run(el, &now) == 1);
+ } while (fr_event_timer_run(el, &now) == 1);
count++;
rs_packet_process(count, event, header, data);
static void rs_collectd_reopen(void *ctx, struct timeval *now)
{
fr_event_list_t *list = ctx;
- static fr_event_t *event;
+ static fr_event_timer_t *event;
struct timeval when;
if (rs_stats_collectd_open(conf) == 0) {
ERROR("Will attempt to re-establish connection in %i ms", RS_SOCKET_REOPEN_DELAY);
rs_tv_add_ms(now, RS_SOCKET_REOPEN_DELAY, &when);
- if (fr_event_insert(list, rs_collectd_reopen, list, &when, &event) < 0) {
+ if (fr_event_timer_insert(list, rs_collectd_reopen, list, &when, &event) < 0) {
ERROR("Failed inserting re-open event");
RS_ASSERT(0);
}
request->thread_ctx = NULL;
request->el = el;
- if (fr_event_insert(request->el, max_request_time_hook,
+ if (fr_event_timer_insert(request->el, max_request_time_hook,
request, &when, &request->ev) < 0) {
REDEBUG("Failed inserting max_request_time");
}
* timer events or FD events will also be
* serviced here.
*/
- rcode = fr_event_check(el, wait_for_event);
+ rcode = fr_event_corral(el, wait_for_event);
if (rcode < 0) {
ERROR("Thread %d failed waiting for request: %s: Exiting",
thread->thread_num, fr_syserror(errno));
/*
* Timer and/or FD events. Go service them.
*/
- (void) fr_event_service(el);
+ fr_event_service(el);
/*
* The server is exiting. Don't dequeue any
struct sockaddr_storage remote_sockaddr;
socklen_t salen;
- fr_event_t *ev_timeout;
- fr_event_t *ev_packet;
+ fr_event_timer_t *ev_timeout;
+ fr_event_timer_t *ev_packet;
struct timeval last_recv;
struct timeval next_recv;
struct timeval last_sent;
/*
* Reset the timers.
*/
- fr_event_delete(session->el, &session->ev_packet);
+ fr_event_timer_delete(session->el, &session->ev_packet);
gettimeofday(&session->last_sent, NULL);
now = session->last_sent;
now.tv_usec -= USEC;
}
- if (fr_event_insert(session->el, bfd_send_packet, session, &now,
+ if (fr_event_timer_insert(session->el, bfd_send_packet, session, &now,
&session->ev_packet) < 0) {
rad_assert("Failed to insert event" == NULL);
}
{
struct timeval now = *when;
- fr_event_delete(session->el, &session->ev_timeout);
+ fr_event_timer_delete(session->el, &session->ev_timeout);
if (session->detection_time >= USEC) {
now.tv_sec += session->detection_time / USEC;
}
}
- if (fr_event_insert(session->el, bfd_detection_timeout, session, &now,
+ if (fr_event_timer_insert(session->el, bfd_detection_timeout, session, &now,
&session->ev_timeout) < 0) {
rad_assert("Failed to insert event" == NULL);
}
static int bfd_stop_control(bfd_state_t *session)
{
- fr_event_delete(session->el, &session->ev_timeout);
- fr_event_delete(session->el, &session->ev_packet);
+ fr_event_timer_delete(session->el, &session->ev_timeout);
+ fr_event_timer_delete(session->el, &session->ev_packet);
return 1;
}
case FR_ACTION_DONE:
(void) fr_heap_extract(request->backlog, request);
- fr_event_delete(request->el, &request->ev);
+ fr_event_timer_delete(request->el, &request->ev);
RDEBUG2("Cleaning up request packet ID %u with timestamp +%d",
request->packet->id,
case FR_ACTION_DONE:
(void) fr_heap_extract(request->backlog, request);
- fr_event_delete(request->el, &request->ev);
+ fr_event_timer_delete(request->el, &request->ev);
RDEBUG2("Cleaning up request packet ID %u with timestamp +%d",
request->packet->id,