]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Rename some functions/structures in event.c
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 8 Nov 2016 19:53:55 +0000 (14:53 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 8 Nov 2016 19:53:55 +0000 (14:53 -0500)
14 files changed:
src/include/detail.h
src/include/event.h
src/include/listen.h
src/include/radiusd.h
src/include/radsniff.h
src/include/realms.h
src/lib/event.c
src/main/interpreter.c
src/main/process.c
src/main/radsniff.c
src/main/threads.c
src/modules/proto_bfd/proto_bfd.c
src/modules/proto_radius/proto_radius_coa.c
src/modules/proto_radius/proto_radius_status.c

index 2c3198e59b8d5d6378950e3761089dc8d59cd922..5a7e2bd5e1fc59e99873dd59ba6ecc2847589bf7 100644 (file)
@@ -45,7 +45,7 @@ typedef enum detail_entry_state_t {
 } 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;
index 4a4c5bc67a1df6e1ebde4d736c488a5e6095e727..622a696c63a9bf40fa3aae63a9a634abcab40a20 100644 (file)
@@ -31,36 +31,36 @@ extern "C" {
 #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
 }
index 1728182bda0a8caf0d707d94fcb749009bf9039d..1379e5ba3b42c6e9a0530b58acf5a8b1d71fc18f 100644 (file)
@@ -104,7 +104,7 @@ struct rad_listen {
         *      Events associated with this listener
         */
        struct timeval          when;
-       fr_event_t              *ev;
+       fr_event_timer_t                *ev;
 
        CONF_SECTION const      *cs;
        void                    *data;
index 958e844d87a1144c57e83a81d41d78b4bedf8534..a8456b348e3485fad6651c026dd481479555db9c 100644 (file)
@@ -289,7 +289,7 @@ struct rad_request {
 #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
index 84961bff9c819e25892793714a22e49ad7d30cc9..4eecec837b8208abac01eb5d51a629587f06239d 100644 (file)
@@ -174,7 +174,7 @@ typedef struct rs_capture {
  */
 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.
 
index da34c04f49be24922bc96214b79e9acbae09e2c8..ecec5cb426949b294d6057cc7531b9224b6f33d3 100644 (file)
@@ -97,7 +97,7 @@ typedef struct home_server {
 
        char const              *secret;
 
-       fr_event_t              *ev;
+       fr_event_timer_t                *ev;
        struct timeval          when;
 
        struct timeval          response_window;
index 8f7e68cb128b1c68af90ada398914151b130ce64..21f7ba25a3aa5ab025293995e665b57f58dd4749 100644 (file)
  * @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$")
 
@@ -37,14 +41,13 @@ 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
@@ -97,11 +100,11 @@ struct fr_event_list_t {
 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;
@@ -113,62 +116,9 @@ static int fr_event_cmp_time_t(void const *a, void const *b)
        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;
@@ -176,6 +126,11 @@ int fr_event_list_num_fds(fr_event_list_t *el)
        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;
@@ -183,12 +138,16 @@ int fr_event_list_num_elements(fr_event_list_t *el)
        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;
 
@@ -196,7 +155,7 @@ int fr_event_delete(fr_event_list_t *el, fr_event_t **parent)
        /*
         *  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;
@@ -227,28 +186,28 @@ int fr_event_delete(fr_event_list_t *el, fr_event_t **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;
        }
 
@@ -260,7 +219,7 @@ int fr_event_insert(fr_event_list_t *el, fr_event_callback_t callback, void *ctx
                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
@@ -270,7 +229,7 @@ int fr_event_insert(fr_event_list_t *el, fr_event_callback_t callback, void *ctx
 
                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;
        }
 
@@ -286,65 +245,50 @@ int fr_event_insert(fr_event_list_t *el, fr_event_callback_t callback, void *ctx
        }
 
        *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
@@ -433,54 +377,92 @@ int fr_event_fd_insert(fr_event_list_t *el, int 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;
@@ -491,49 +473,29 @@ int fr_event_check(fr_event_list_t *el, bool wait)
         */
        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);
 
@@ -545,20 +507,26 @@ int fr_event_check(fr_event_list_t *el, bool wait)
                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;
 
@@ -596,27 +564,114 @@ int fr_event_service(fr_event_list_t *el)
                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
 
@@ -685,13 +740,13 @@ int main(int argc, char **argv)
                        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;
index 0f2da5d17c9977e3b8c6aabf811be464b4cade66..a7507f33516862b365ab34df515cf2ebf9970eb1 100644 (file)
@@ -1257,7 +1257,7 @@ rlm_rcode_t unlang_interpret(REQUEST *request, CONF_SECTION *cs, rlm_rcode_t act
        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 {
@@ -1267,13 +1267,13 @@ 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;
        }
 
@@ -1350,7 +1350,7 @@ int unlang_event_timeout_add(REQUEST *request, fr_unlang_timeout_callback_t call
        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;
@@ -1551,7 +1551,7 @@ int unlang_delay(REQUEST *request, struct timeval *delay, fr_request_process_t p
        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;
        }
index a06883706e3f7796cf723a8a08220397352d3950..11de5b4b71a1e563c7111106110a2328a034085e 100644 (file)
@@ -134,7 +134,7 @@ static void request_timer(void *ctx, struct timeval *now);
 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());
        }
 }
@@ -382,7 +382,7 @@ static void coa_separate(REQUEST *request) CC_HINT(nonnull);
 #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()); \
        }
 
@@ -563,9 +563,9 @@ void request_delete(REQUEST *request)
 #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);
        }
 
        /*
@@ -818,7 +818,7 @@ bool request_max_time(REQUEST *request)
        /*
         *      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;
 
@@ -957,7 +957,7 @@ static void request_cleanup_delay(REQUEST *request, fr_state_action_t action)
 #endif
 
        case FR_ACTION_TIMER:
-               fr_event_now(el, &now);
+               fr_event_list_time(&now, el);
 
                rad_assert(request->root->cleanup_delay > 0);
 
@@ -1029,7 +1029,7 @@ static void request_response_delay(REQUEST *request, fr_state_action_t action)
 #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,
@@ -1861,7 +1861,7 @@ static void tcp_socket_timer(void *ctx, struct timeval *now)
 
        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
@@ -2623,7 +2623,7 @@ static void proxy_wait_for_id(REQUEST *request, fr_state_action_t action)
                }
 #endif
 
-               fr_event_now(el, &now);
+               fr_event_list_time(&now, el);
                when = request->proxy->packet->timestamp;
 
 #ifdef WITH_COA
@@ -3457,7 +3457,7 @@ static void request_ping(REQUEST *request, fr_state_action_t action)
                /*
                 *      Remove the request from any hashes
                 */
-               fr_event_delete(el, &request->ev);
+               fr_event_timer_delete(el, &request->ev);
                remove_from_proxy_hash(request);
 
                /*
@@ -3706,7 +3706,7 @@ static void mark_home_server_alive(REQUEST *request, home_server_t *home)
        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,
@@ -3752,7 +3752,7 @@ static void mark_home_server_zombie(home_server_t *home, struct timeval *now, st
        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;
@@ -3824,7 +3824,7 @@ void revive_home_server(void *ctx, UNUSED struct timeval *now)
         *      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)),
@@ -4049,7 +4049,7 @@ static void proxy_wait_for_reply(REQUEST *request, fr_state_action_t action)
        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:
@@ -4377,7 +4377,7 @@ static bool coa_keep_waiting(REQUEST *request)
                return false;
        }
 
-       fr_event_now(el, &now);
+       fr_event_list_time(&now, el);
 
        if (request->delay == 0) {
                /*
@@ -5022,7 +5022,7 @@ static int event_new_fd(rad_listen_t *this)
        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);
@@ -5046,9 +5046,9 @@ static void sd_watchdog_event(void *ctx)
        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");
        }
 }
@@ -5481,7 +5481,7 @@ static int request_delete_cb(UNUSED void *ctx, void *data)
 #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",
index f3616fb75b7b2c020bb5edd463029585906affd8..11e2d690bf163548fc66ab8cb8adbba62eaca75b 100644 (file)
@@ -845,12 +845,12 @@ clear:
        }
 
        {
-               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");
                }
        }
@@ -880,7 +880,7 @@ static void rs_stats_update_latency(rs_latency_t *stats, struct timeval *latency
 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));
@@ -919,7 +919,7 @@ static int rs_install_stats_processor(rs_stats_t *stats, fr_event_list_t *el,
                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;
        }
@@ -984,7 +984,7 @@ static int _request_free(rs_request_t *request)
        }
 
        if (request->event) {
-               ret = fr_event_delete(events, &request->event);
+               ret = fr_event_timer_delete(events, &request->event);
                RS_ASSERT(ret);
        }
 
@@ -1424,7 +1424,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt
                                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.
                         */
@@ -1439,7 +1439,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt
                         */
                        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
@@ -1608,7 +1608,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt
                        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.
                 */
@@ -1669,7 +1669,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt
                 */
                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");
 
@@ -1811,7 +1811,7 @@ static void rs_got_packet(fr_event_list_t *el, int fd, void *ctx)
 
                        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);
@@ -2001,7 +2001,7 @@ static void _unmark_link(void *request)
 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) {
@@ -2012,7 +2012,7 @@ static void rs_collectd_reopen(void *ctx, struct timeval *now)
        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);
        }
index a05db68ed1767d9c271cab32cffb362d9926cf4e..13e4f4d10da84ae2bc04790b1a62ae69d26f4131 100644 (file)
@@ -520,7 +520,7 @@ static void *thread_handler(void *arg)
                                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");
                                }
@@ -551,7 +551,7 @@ static void *thread_handler(void *arg)
                 *      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));
@@ -568,7 +568,7 @@ static void *thread_handler(void *arg)
                /*
                 *      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
index cb3202d78c641a8fe9c6dbae13074a78de7abe5d..3d9d08538fb281e12db90ae15c3a18e11ae79087 100644 (file)
@@ -88,8 +88,8 @@ typedef struct bfd_state_t {
        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;
@@ -884,7 +884,7 @@ static int bfd_start_packets(bfd_state_t *session)
        /*
         *      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;
@@ -919,7 +919,7 @@ static int bfd_start_packets(bfd_state_t *session)
                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);
        }
@@ -932,7 +932,7 @@ static void bfd_set_timeout(bfd_state_t *session, struct timeval *when)
 {
        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;
@@ -960,7 +960,7 @@ static void bfd_set_timeout(bfd_state_t *session, struct timeval *when)
                }
        }
 
-       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);
        }
@@ -993,8 +993,8 @@ static int bfd_start_control(bfd_state_t *session)
 
 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;
 }
 
index e8ebc57b2adb1906ea9bce80dcd1853bc9981c65..cab047e6dc0cf8d309db3f5cfd6ab6ac94276dc3 100644 (file)
@@ -298,7 +298,7 @@ static void coa_queued(REQUEST *request, fr_state_action_t action)
 
        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,
index c3b3d839c31ff40707bf58b814f4c75034cfe48c..b1186dcdb533c6de7dea93bc9ffbea639b9727e8 100644 (file)
@@ -259,7 +259,7 @@ static void status_queued(REQUEST *request, fr_state_action_t action)
 
        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,