From: Alan T. DeKok Date: Mon, 21 Nov 2016 20:05:36 +0000 (-0500) Subject: add EVFILT_USER callbacks X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcfd715f8b8bc8b00d6989e003de5a496f0fb861;p=thirdparty%2Ffreeradius-server.git add EVFILT_USER callbacks --- diff --git a/src/include/event.h b/src/include/event.h index 6f33aac12c2..e9449e2bfee 100644 --- a/src/include/event.h +++ b/src/include/event.h @@ -26,6 +26,8 @@ */ RCSIDH(event_h, "$Id$") +#include + #ifdef __cplusplus extern "C" { #endif @@ -37,6 +39,7 @@ typedef struct fr_event_timer_t fr_event_timer_t; typedef void (*fr_event_callback_t)(void *, struct timeval *now); typedef int (*fr_event_status_t)(void *status_ctx, struct timeval *); typedef void (*fr_event_fd_handler_t)(fr_event_list_t *el, int sock, void *ctx); +typedef void (*fr_event_user_handler_t)(int kq, struct kevent const *kev, void *ctx); int fr_event_list_num_fds(fr_event_list_t *el); int fr_event_list_num_elements(fr_event_list_t *el); @@ -55,6 +58,9 @@ int fr_event_timer_insert(fr_event_list_t *el, void const *ctx, struct timeval *when, fr_event_timer_t **parent); int fr_event_timer_run(fr_event_list_t *el, struct timeval *when); +int fr_event_user_insert(fr_event_list_t *el, fr_event_user_handler_t user, void *ctx) CC_HINT(nonnull(1,2)); +int fr_event_user_delete(fr_event_list_t *el, fr_event_user_handler_t user, void *ctx) CC_HINT(nonnull(1,2)); + int fr_event_corral(fr_event_list_t *el, bool wait); void fr_event_service(fr_event_list_t *el); diff --git a/src/lib/event.c b/src/lib/event.c index d71a650a767..c9f77a2d712 100644 --- a/src/lib/event.c +++ b/src/lib/event.c @@ -31,8 +31,6 @@ RCSID("$Id$") #include #include -#include - #define FR_EV_BATCH_FDS (256) #undef USEC @@ -60,7 +58,7 @@ typedef struct fr_event_fd_t { fr_event_fd_handler_t write; //!< callback for when we can write data. fr_event_fd_handler_t error; //!< callback for when an error occurs on the FD. - void *ctx; //!< Context pointer to pass to each callback. + void *ctx; //!< context pointer to pass to each file descriptor callback. } fr_event_fd_t; /** Stores all information relating to an event list @@ -83,6 +81,8 @@ struct fr_event_list_t { int kq; //!< instance association with this event list. + fr_event_user_handler_t user; //!< callback for EVFILT_USER events + void *user_ctx; //!< context pointer to pass to the user callback struct kevent events[FR_EV_BATCH_FDS]; /* so it doesn't go on the stack every time */ }; @@ -421,6 +421,45 @@ int fr_event_timer_insert(fr_event_list_t *el, fr_event_callback_t callback, voi return 0; } + +/** Add a user callback to the event list. + * + * @param[in] el containing the timer events. + * @param[in] user the callback for EVFILT_USER + * @param[in] ctx user context for the callback + * @return + * - < 0 on error + * - 0 on success + */ +int fr_event_user_insert(fr_event_list_t *el, fr_event_user_handler_t user, void *ctx) +{ + el->user = user; + el->user_ctx = ctx; + + return 0; +} + + +/** Delete a user callback to the event list. + * + * @param[in] el containing the timer events. + * @param[in] user the callback for EVFILT_USER + * @param[in] ctx user context for the callback + * @return + * - < 0 on error + * - 0 on success + */ +int fr_event_user_delete(fr_event_list_t *el, fr_event_user_handler_t user, void *ctx) +{ + if ((el->user != user) || (el->user_ctx != ctx)) return -1; + + el->user = NULL; + el->user_ctx = NULL; + + return 0; +} + + /** Run a single scheduled timer event * * @param[in] el containing the timer events. @@ -581,6 +620,7 @@ void fr_event_service(fr_event_list_t *el) if (ev->read && (el->events[i].flags & EVFILT_READ)) ev->read(el, ev->fd, ev->ctx); if (ev->write && (el->events[i].flags & EVFILT_WRITE)) ev->write(el, ev->fd, ev->ctx); + if (el->user && (el->events[i].flags & EVFILT_USER)) el->user(el->kq, &el->events[i], el->user_ctx); } if (fr_heap_num_elements(el->times) > 0) {