]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
fix up dlist functions.
authorAlan T. DeKok <aland@freeradius.org>
Thu, 12 Jul 2018 15:32:27 +0000 (11:32 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 12 Jul 2018 15:32:27 +0000 (11:32 -0400)
Add a separate `fr_dlist_head_t`, which contains an offset
of the encapsulating structure.

And then fix up the various functions to take a head / ptr
instead of "entry".  That way the caller doesn't have to play
dumb games with `fr_dlist_t *entry = ...` and various casts.

19 files changed:
src/lib/io/channel.h
src/lib/io/network.c
src/lib/io/schedule.c
src/lib/io/time.c
src/lib/io/time.h
src/lib/io/worker.c
src/lib/util/dlist.h
src/lib/util/event.c
src/main/exec.c
src/main/state.c
src/modules/proto_detail/proto_detail.h
src/modules/proto_detail/proto_detail_work.c
src/modules/rlm_radius/rlm_radius.c
src/modules/rlm_radius/rlm_radius.h
src/modules/rlm_radius/rlm_radius_udp.c
src/modules/rlm_radius/track.c
src/modules/rlm_radius/track.h
src/modules/rlm_stats/rlm_stats.c
src/unlang/op.c

index f7bc600d6a6c5d1326d602e3076aac295e40d1b4..35d881db21d531da0a86208e507a8f2f5fae6ce2 100644 (file)
@@ -96,7 +96,7 @@ typedef struct fr_channel_data_t {
        union {
                struct {
                        fr_time_t               *recv_time;     //!< time original request was received (network -> worker)
-                       fr_dlist_t              list;           //!< list of unprocessed packets for the worker
+                       fr_dlist_t              entry;          //!< list of unprocessed packets for the worker
                        bool                    is_dup;         //!< dup, new, etc.
                } request;
 
index 9d2c873ef967cb131f78d3a811da8536380b6044..6b8eb888d315986a043bf4c9f3a4a690923f67b7 100644 (file)
@@ -34,7 +34,6 @@ RCSID("$Id$")
 #include <freeradius-devel/io/worker.h>
 #include <freeradius-devel/io/network.h>
 #include <freeradius-devel/io/listen.h>
-#include <freeradius-devel/util/dlist.h>
 
 /*
  *     Define our own debugging.
@@ -85,8 +84,6 @@ typedef struct fr_network_socket_t {
 
        fr_channel_data_t       *pending;               //!< the currently pending partial packet
        fr_heap_t               *waiting;               //!< packets waiting to be written
-
-       fr_dlist_t              entry;                  //!< for deleted sockets
 } fr_network_socket_t;
 
 /*
@@ -741,7 +738,6 @@ static void fr_network_socket_callback(void *ctx, void const *data, size_t data_
        memcpy(&s->listen, data, sizeof(s->listen));
 
        MEM(s->waiting = fr_heap_create(s, waiting_cmp, fr_channel_data_t, channel.heap_id));
-       FR_DLIST_INIT(s->entry);
 
        talloc_set_destructor(s, _network_socket_free);
 
@@ -815,7 +811,6 @@ static void fr_network_directory_callback(void *ctx, void const *data, size_t da
        memcpy(&s->listen, data, sizeof(s->listen));
 
        MEM(s->waiting = fr_heap_create(s, waiting_cmp, fr_channel_data_t, channel.heap_id));
-       FR_DLIST_INIT(s->entry);
 
        talloc_set_destructor(s, _network_socket_free);
 
index ff1b84bbbbcd3fbd2f83f9b6b68529f3d3cb2ccc..55808bbb16b5c0652ad017bcfed802b75b2e445f 100644 (file)
@@ -132,7 +132,7 @@ struct fr_schedule_t {
        fr_schedule_thread_instantiate_t        worker_thread_instantiate;      //!< thread instantiation callback
        void                                    *worker_instantiate_ctx;        //!< thread instantiation context
 
-       fr_dlist_t      workers;                //!< list of workers
+       fr_dlist_head_t workers;                //!< list of workers
 
        fr_network_t    *single_network;        //!< for single-threaded mode
        fr_worker_t     *single_worker;         //!< for single-threaded mode
@@ -362,7 +362,7 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el,
 {
 #ifdef HAVE_PTHREAD_H
        int i;
-       fr_dlist_t *entry, *next;
+       fr_schedule_worker_t *sw, *next;
 #endif
        fr_schedule_t *sc;
 
@@ -439,7 +439,7 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el,
        /*
         *      Create the list which holds the workers.
         */
-       FR_DLIST_INIT(sc->workers);
+       fr_dlist_init(&sc->workers, offsetof(fr_schedule_worker_t, entry));
 
        memset(&sc->semaphore, 0, sizeof(sc->semaphore));
        if (sem_init(&sc->semaphore, 0, SEMAPHORE_LOCKED) != 0) {
@@ -474,8 +474,6 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el,
         *      Create all of the workers.
         */
        for (i = 0; i < sc->max_workers; i++) {
-               fr_schedule_worker_t *sw;
-
                fr_log(sc->log, L_DBG, "Creating %d/%d workers\n", i, sc->max_workers);
 
                /*
@@ -490,7 +488,7 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el,
                sw->id = i;
                sw->sc = sc;
                sw->status = FR_CHILD_INITIALIZING;
-               fr_dlist_insert_head(&sc->workers, &sw->entry);
+               fr_dlist_insert_head(&sc->workers, sw);
 
                if (fr_schedule_pthread_create(&sw->pthread_id, fr_schedule_worker_thread, sw) < 0) {
                        fr_log(sc->log, L_ERR, "Failed creating worker %d: %s\n", i, fr_strerror());
@@ -514,18 +512,15 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el,
        /*
         *      See if all of the workers have started.
         */
-       for (entry = FR_DLIST_FIRST(sc->workers);
-            entry != NULL;
-            entry = next) {
-               fr_schedule_worker_t *sw;
-
-               next = FR_DLIST_NEXT(sc->workers, entry);
+       for (sw = fr_dlist_first(&sc->workers);
+            sw != NULL;
+            sw = next) {
 
-               sw = fr_ptr_to_type(fr_schedule_worker_t, entry, entry);
+               next = fr_dlist_next(&sc->workers, sw);
 
                if (sw->status != FR_CHILD_RUNNING) {
                        sc->num_workers--;
-                       fr_dlist_remove(entry);
+                       fr_dlist_remove(&sc->workers, sw);
                        continue;
                }
        }
@@ -560,8 +555,6 @@ int fr_schedule_destroy(fr_schedule_t *sc)
        sc->running = false;
 
 #ifdef HAVE_PTHREAD_H
-       fr_dlist_t      *entry;
-
        /*
         *      Single threaded mode: kill the only network / worker we have.
         */
@@ -592,10 +585,9 @@ int fr_schedule_destroy(fr_schedule_t *sc)
        /*
         *      Signal all of the workers to exit.
         */
-       for (entry = FR_DLIST_FIRST(sc->workers);
-            entry != NULL;
-            entry = FR_DLIST_NEXT(sc->workers, entry)) {
-               sw = fr_ptr_to_type(fr_schedule_worker_t, entry, entry);
+       for (sw = fr_dlist_first(&sc->workers);
+            sw != NULL;
+            sw = fr_dlist_next(&sc->workers, sw)) {
                fr_worker_exit(sw->worker);
        }
 
@@ -612,9 +604,10 @@ int fr_schedule_destroy(fr_schedule_t *sc)
        /*
         *      Clean up the exited workers.
         */
-       while ((entry = FR_DLIST_FIRST(sc->workers)) != NULL) {
+       while ((sw = fr_dlist_first(&sc->workers)) != NULL) {
                sc->num_workers--;
-               fr_dlist_remove(entry);
+
+               fr_dlist_remove(&sc->workers, sw);
 
                /*
                 *      Ensure that the thread has exited before
@@ -624,7 +617,6 @@ int fr_schedule_destroy(fr_schedule_t *sc)
                 *      exited before the main thread cleans up the
                 *      module instances.
                 */
-               sw = fr_ptr_to_type(fr_schedule_worker_t, entry, entry);
                if (pthread_join(sw->pthread_id, NULL) != 0) {
                        fr_log(sc->log, L_ERR, "Failed joining worker %i: %s", sw->id, fr_syserror(errno));
                } else {
index abc28e7d42db0a64d6838f61acdac8a3d3db203a..596d38f5e129c12e41c8fb445749285b2643080c 100644 (file)
@@ -148,7 +148,7 @@ void fr_time_to_timeval(struct timeval *tv, fr_time_t when)
  * @param[in] tt the time tracking structure.
  * @param[in] when the event happened
  */
-void fr_time_tracking_start(fr_time_tracking_t *tt, fr_time_t when)
+void fr_time_tracking_start(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker)
 {
        memset(tt, 0, sizeof(*tt));
 
@@ -156,7 +156,8 @@ void fr_time_tracking_start(fr_time_tracking_t *tt, fr_time_t when)
        tt->start = when;
        tt->resumed = when;
 
-       FR_DLIST_INIT(tt->list);
+       fr_dlist_init(&(worker->list), offsetof(fr_time_tracking_t, list.entry));
+       fr_dlist_entry_init(&tt->list.entry);
 }
 
 
@@ -180,8 +181,8 @@ void fr_time_tracking_end(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracki
        /*
         *      This request cannot be in any list.
         */
-       rad_assert(tt->list.prev == &tt->list);
-       rad_assert(tt->list.next == &tt->list);
+       rad_assert(tt->list.entry.prev == &(tt->list.entry));
+       rad_assert(tt->list.entry.next == &(tt->list.entry));
 
        /*
         *      Update the time that the worker spent processing the request.
@@ -215,7 +216,7 @@ void fr_time_tracking_yield(fr_time_tracking_t *tt, fr_time_t when, fr_time_trac
         *      Insert this request into the TAIL of the worker's list
         *      of waiting requests.
         */
-       fr_dlist_insert_head(&worker->list, &tt->list);
+       fr_dlist_insert_head(&worker->list, tt);
 }
 
 
@@ -224,7 +225,7 @@ void fr_time_tracking_yield(fr_time_tracking_t *tt, fr_time_t when, fr_time_trac
  * @param[in] tt the time tracking structure.
  * @param[in] when the event happened
  */
-void fr_time_tracking_resume(fr_time_tracking_t *tt, fr_time_t when)
+void fr_time_tracking_resume(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker)
 {
        tt->when = when;
        tt->resumed = when;
@@ -237,7 +238,7 @@ void fr_time_tracking_resume(fr_time_tracking_t *tt, fr_time_t when)
         *      Remove this request into the workers list of waiting
         *      requests.
         */
-       fr_dlist_remove(&tt->list);
+       fr_dlist_remove(&worker->list, tt);
 }
 
 
index 9950a555328bcae86a9fa10dfb0ca5e3cbd59259..686bb2f2e63564f27d857992996f7dd2d7bcd59f 100644 (file)
@@ -68,7 +68,7 @@ typedef struct fr_time_tracking_t {
        fr_time_t       running;                //!< total time spent running
        fr_time_t       waiting;                //!< total time spent waiting
 
-       fr_dlist_t      list;                   //!< for linking a request to various lists
+       fr_dlist_head_t list;                   //!< for linking a request to various lists
 } fr_time_tracking_t;
 
 #define NANOSEC (1000000000)
@@ -78,10 +78,10 @@ int fr_time_start(void);
 fr_time_t fr_time(void);
 void fr_time_to_timeval(struct timeval *tv, fr_time_t when) CC_HINT(nonnull);
 
-void fr_time_tracking_start(fr_time_tracking_t *tt, fr_time_t when) CC_HINT(nonnull);
+void fr_time_tracking_start(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker) CC_HINT(nonnull);
 void fr_time_tracking_end(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker) CC_HINT(nonnull);
 void fr_time_tracking_yield(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker) CC_HINT(nonnull);
-void fr_time_tracking_resume(fr_time_tracking_t *tt, fr_time_t when) CC_HINT(nonnull);
+void fr_time_tracking_resume(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker) CC_HINT(nonnull);
 void fr_time_tracking_debug(fr_time_tracking_t *tt, FILE *fp) CC_HINT(nonnull);
 
 #ifdef __cplusplus
index f5a79de72c4acc093719c9f5df920da4ee5f5380..3bf55e4798870ec17bf063d154ea0b2730e64f48 100644 (file)
@@ -72,7 +72,7 @@ RCSID("$Id$")
  *  Track things by priority and time.
  */
 typedef struct fr_worker_heap_t {
-       fr_dlist_t      list;                   //!< list of things, ordered by time.
+       fr_dlist_head_t list;                   //!< list of things, ordered by time.
        fr_heap_t       *heap;                  //!< heap, ordered by priority
 } fr_worker_heap_t;
 
@@ -165,9 +165,9 @@ static void fr_worker_post_event(fr_event_list_t *el, struct timeval *now, void
  *     We need wrapper macros because we have multiple instances of
  *     the same code.
  */
-#define WORKER_HEAP_INIT(_name, _func, _type, _member) do { \
-               FR_DLIST_INIT(worker->_name.list); \
-               worker->_name.heap = fr_heap_create(worker, _func, _type, _member); \
+#define WORKER_HEAP_INIT(_name, _func) do { \
+               fr_dlist_init(&worker->_name.list, offsetof(fr_channel_data_t, request.entry)); \
+               worker->_name.heap = fr_heap_create(worker, _func, fr_channel_data_t, channel.heap_id); \
                if (!worker->_name.heap) { \
                        (void) fr_event_user_delete(worker->el, fr_worker_evfilt_user, worker); \
                        talloc_free(worker); \
@@ -175,19 +175,19 @@ static void fr_worker_post_event(fr_event_list_t *el, struct timeval *now, void
                } \
        } while (0)
 
-#define WORKER_HEAP_INSERT(_name, _var, _member) do { \
-               fr_dlist_insert_head(&worker->_name.list, &_var->_member); \
-               (void) fr_heap_insert(worker->_name.heap, _var);        \
+#define WORKER_HEAP_INSERT(_name, _var) do { \
+               (void) fr_heap_insert(worker->_name.heap, _var);       \
+               fr_dlist_insert_head(&worker->_name.list, _var);       \
        } while (0)
 
-#define WORKER_HEAP_POP(_name, _var, _member) do { \
-               _var = fr_heap_pop(worker->_name.heap); \
-               if (_var) fr_dlist_remove(&_var->_member); \
+#define WORKER_HEAP_POP(_name, _var) do { \
+               _var = fr_heap_pop(worker->_name.heap);                \
+               if (_var) fr_dlist_remove(&worker->_name.list, _var);  \
        } while (0)
 
-#define WORKER_HEAP_EXTRACT(_name, _var, _member) do { \
-               (void) fr_heap_extract(worker->_name.heap, _var); \
-               fr_dlist_remove(&_var->_member);                         \
+#define WORKER_HEAP_EXTRACT(_name, _var) do { \
+               (void) fr_heap_extract(worker->_name.heap, _var);       \
+               fr_dlist_remove(&worker->_name.list, _var);            \
        } while (0)
 
 
@@ -211,7 +211,7 @@ static bool fr_worker_drain_input(fr_worker_t *worker, fr_channel_t *ch, fr_chan
                worker->num_requests++;
                DEBUG3("\t%sreceived request %d", worker->name, worker->num_requests);
                cd->channel.ch = ch;
-               WORKER_HEAP_INSERT(to_decode, cd, request.list);
+               WORKER_HEAP_INSERT(to_decode, cd);
        } while ((cd = fr_channel_recv_request(ch)) != NULL);
 
        return true;
@@ -568,7 +568,7 @@ finished:
        request->async->original_recv_time = NULL;
        request->async->el = NULL;
        request->async->process = NULL;
-       fr_dlist_remove(&request->async->tracking.list);
+       fr_dlist_remove(&worker->tracking.list, &request->async->tracking);
        request->async->channel = NULL;
        request->async->packet_ctx = NULL;
        request->async->listen = NULL;
@@ -584,7 +584,7 @@ finished:
  */
 static void worker_stop_request(fr_worker_t *worker, REQUEST *request, fr_time_t now)
 {
-       fr_time_tracking_resume(&request->async->tracking, now);
+       fr_time_tracking_resume(&request->async->tracking, now, &worker->tracking);
        (void) request->async->process(request->async->process_inst, request, FR_IO_ACTION_DONE);
 
        /*
@@ -695,7 +695,7 @@ static void worker_reset_timer(fr_worker_t *worker)
  */
 static void fr_worker_check_timeouts(fr_worker_t *worker, fr_time_t now)
 {
-       fr_dlist_t *entry;
+       fr_channel_data_t *cd;
        fr_time_t waiting;
 
        /*
@@ -704,10 +704,7 @@ static void fr_worker_check_timeouts(fr_worker_t *worker, fr_time_t now)
         *      We check it before the "to_decode" list, so that we
         *      don't check packets twice.
         */
-       while ((entry = FR_DLIST_TAIL(worker->localized.list)) != NULL) {
-               fr_channel_data_t *cd;
-
-               cd = fr_ptr_to_type(fr_channel_data_t, request.list, entry);
+       while ((cd = fr_dlist_tail(&worker->localized.list)) != NULL) {
                waiting = now - cd->m.when;
 
                if (waiting < ((worker->max_request_time - 2) * (fr_time_t) NANOSEC)) break;
@@ -715,7 +712,7 @@ static void fr_worker_check_timeouts(fr_worker_t *worker, fr_time_t now)
                /*
                 *      Waiting too long, delete it.
                 */
-               WORKER_HEAP_EXTRACT(localized, cd, request.list);
+               WORKER_HEAP_EXTRACT(localized, cd);
                DEBUG3("TIMEOUT: Extracting packet from localized list");
                fr_worker_nak(worker, cd, now);
        }
@@ -723,11 +720,9 @@ static void fr_worker_check_timeouts(fr_worker_t *worker, fr_time_t now)
        /*
         *      Check the "to_decode" queue for old packets.
         */
-       while ((entry = FR_DLIST_TAIL(worker->to_decode.list)) != NULL) {
+       while ((cd = fr_dlist_tail(&worker->to_decode.list)) != NULL) {
                fr_message_t *lm;
-               fr_channel_data_t *cd;
 
-               cd = fr_ptr_to_type(fr_channel_data_t, request.list, entry);
                waiting = now - cd->m.when;
 
                if (waiting < (NANOSEC / 100)) break;
@@ -736,7 +731,7 @@ static void fr_worker_check_timeouts(fr_worker_t *worker, fr_time_t now)
                 *      Waiting too long, delete it.
                 */
                if (waiting > NANOSEC) {
-                       WORKER_HEAP_EXTRACT(to_decode, cd, request.list);
+                       WORKER_HEAP_EXTRACT(to_decode, cd);
                        DEBUG3("TIMEOUT: Extracting packet from to_decode list");
 
                nak:
@@ -747,7 +742,7 @@ static void fr_worker_check_timeouts(fr_worker_t *worker, fr_time_t now)
                /*
                 *      0.01 to 1s.  Localize it.
                 */
-               WORKER_HEAP_EXTRACT(to_decode, cd, request.list);
+               WORKER_HEAP_EXTRACT(to_decode, cd);
                lm = fr_message_localize(worker, &cd->m, sizeof(*cd));
                if (!lm) {
                        DEBUG3("TIMEOUT: Failed localizing message from to_decode list: %s", fr_strerror());
@@ -755,7 +750,7 @@ static void fr_worker_check_timeouts(fr_worker_t *worker, fr_time_t now)
                }
                cd = (fr_channel_data_t *) lm;
 
-               WORKER_HEAP_INSERT(localized, cd, request.list);
+               WORKER_HEAP_INSERT(localized, cd);
        }
 }
 
@@ -787,7 +782,7 @@ static REQUEST *fr_worker_get_request(fr_worker_t *worker, fr_time_t now)
                DEBUG3("Worker %i found runnable request", fr_schedule_worker_id());
                REQUEST_VERIFY(request);
                rad_assert(request->runnable_id < 0);
-               fr_time_tracking_resume(&request->async->tracking, now);
+               fr_time_tracking_resume(&request->async->tracking, now, &worker->tracking);
                return request;
        }
 
@@ -796,9 +791,9 @@ static REQUEST *fr_worker_get_request(fr_worker_t *worker, fr_time_t now)
         *      the "to_decode" queue.
         */
        do {
-               WORKER_HEAP_POP(localized, cd, request.list);
+               WORKER_HEAP_POP(localized, cd);
                if (!cd) {
-                       WORKER_HEAP_POP(to_decode, cd, request.list);
+                       WORKER_HEAP_POP(to_decode, cd);
                }
                if (!cd) {
                        DEBUG3("Worker %i localized and decode lists are empty", fr_schedule_worker_id());
@@ -975,7 +970,7 @@ nak:
         *      Bootstrap the async state machine with the initial
         *      state of the request.
         */
-       fr_time_tracking_start(&request->async->tracking, now);
+       fr_time_tracking_start(&request->async->tracking, now, &worker->tracking);
        worker->num_active++;
        rad_assert(request->runnable_id < 0);
 
@@ -1210,13 +1205,13 @@ void fr_worker_destroy(fr_worker_t *worker)
         *      mark them as unused.
         */
        while (true) {
-               WORKER_HEAP_POP(to_decode, cd, request.list);
+               WORKER_HEAP_POP(to_decode, cd);
                if (!cd) break;
                fr_message_done(&cd->m);
        }
 
        while (true) {
-               WORKER_HEAP_POP(localized, cd, request.list);
+               WORKER_HEAP_POP(localized, cd);
                if (!cd) break;
                fr_message_done(&cd->m);
        }
@@ -1312,7 +1307,7 @@ nomem:
         *      the worker thread is running.
         */
        memset(&worker->tracking, 0, sizeof(worker->tracking));
-       FR_DLIST_INIT(worker->tracking.list);
+       fr_dlist_init(&worker->tracking.list, offsetof(fr_time_tracking_t, list.entry));
 
        worker->kq = fr_event_list_kq(worker->el);
        rad_assert(worker->kq >= 0);
@@ -1344,8 +1339,8 @@ nomem:
                goto fail2;
        }
 
-       WORKER_HEAP_INIT(to_decode, worker_message_cmp, fr_channel_data_t, channel.heap_id);
-       WORKER_HEAP_INIT(localized, worker_message_cmp, fr_channel_data_t, channel.heap_id);
+       WORKER_HEAP_INIT(to_decode, worker_message_cmp);
+       WORKER_HEAP_INIT(localized, worker_message_cmp);
 
        worker->runnable = fr_heap_talloc_create(worker, worker_runnable_cmp, REQUEST, runnable_id);
        if (!worker->runnable) {
index f9543dd0684627243b6456de23c8d795c70668fe..9a31e0916434a21141d1bb59d0bb26ad52b4aa6d 100644 (file)
@@ -33,12 +33,30 @@ typedef struct fr_dlist_t {
        struct fr_dlist_t *next;
 } fr_dlist_t;
 
+typedef struct fr_dlist_head_t {
+       size_t          offset;
+       fr_dlist_t      entry;
+} fr_dlist_head_t;
+
 /*
  *     Functions to manage a doubly linked list.
  */
-#define FR_DLIST_INIT(head) do { head.prev = head.next = &head; } while (0)
-static inline void fr_dlist_insert_head(fr_dlist_t *head, fr_dlist_t *entry)
+static inline void fr_dlist_entry_init(fr_dlist_t *entry)
+{
+       entry->prev = entry->next = entry;
+}
+
+static inline void fr_dlist_init(fr_dlist_head_t *head, size_t offset)
+{
+       fr_dlist_entry_init(&head->entry);
+       head->offset = offset;
+}
+
+static inline void fr_dlist_insert_head(fr_dlist_head_t *list_head, void *ptr)
 {
+       fr_dlist_t *entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset);
+       fr_dlist_t *head = &(list_head->entry);
+
        if (!fr_cond_assert(head->next != NULL)) return;
        if (!fr_cond_assert(head->prev != NULL)) return;
 
@@ -48,8 +66,11 @@ static inline void fr_dlist_insert_head(fr_dlist_t *head, fr_dlist_t *entry)
        head->next = entry;
 }
 
-static inline void fr_dlist_insert_tail(fr_dlist_t *head, fr_dlist_t *entry)
+static inline void fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr)
 {
+       fr_dlist_t *entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset);
+       fr_dlist_t *head = &(list_head->entry);
+
        if (!fr_cond_assert(head->next != NULL)) return;
        if (!fr_cond_assert(head->prev != NULL)) return;
 
@@ -63,8 +84,10 @@ static inline void fr_dlist_insert_tail(fr_dlist_t *head, fr_dlist_t *entry)
 /*
  *     Insert one list into the tail of another
  */
-static inline void fr_dlist_insert_tail_list(fr_dlist_t *head, fr_dlist_t *list)
+static inline void fr_dlist_insert_tail_list(fr_dlist_head_t *list_head, fr_dlist_t *list)
 {
+       fr_dlist_t *head = &(list_head->entry);
+
        if (!fr_cond_assert(head->next != NULL)) return;
        if (!fr_cond_assert(head->prev != NULL)) return;
 
@@ -78,8 +101,10 @@ static inline void fr_dlist_insert_tail_list(fr_dlist_t *head, fr_dlist_t *list)
 }
 #endif
 
-static inline void fr_dlist_remove(fr_dlist_t *entry)
+static inline void fr_dlist_remove(fr_dlist_head_t *list_head, void *ptr)
 {
+       fr_dlist_t *entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset);
+
        if (!fr_cond_assert(entry->next != NULL)) return;
        if (!fr_cond_assert(entry->prev != NULL)) return;
 
@@ -88,10 +113,37 @@ static inline void fr_dlist_remove(fr_dlist_t *entry)
        entry->prev = entry->next = entry;
 }
 
-#define FR_DLIST_FIRST(head) ((head.next == &head) ? NULL : head.next)
-#define FR_DLIST_NEXT(head, p_entry) ((p_entry->next == &head) ? NULL : p_entry->next)
-#define FR_DLIST_TAIL(head) ((head.prev == &head) ? NULL : head.prev)
+static inline void *fr_dlist_next(fr_dlist_head_t *list_head, void *ptr)
+{
+       fr_dlist_t *entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset);
+       fr_dlist_t *head = &(list_head->entry);
+
+       if (entry->next == head) return NULL;
+       entry = entry->next;
+       return (void *) (((uint8_t *) entry) - list_head->offset);
+}
 
+static inline void *fr_dlist_first(fr_dlist_head_t *list_head)
+{
+       fr_dlist_t *head = &(list_head->entry);
+
+       if (head->next == head) return NULL;
+
+       return (void *) (((uint8_t *) head->next) - list_head->offset);
+
+}
+
+static inline void *fr_dlist_tail(fr_dlist_head_t *list_head)
+{
+       fr_dlist_t *head = &(list_head->entry);
+
+       if (head->prev == head) return NULL;
+
+       return (void *) (((uint8_t *) head->prev) - list_head->offset);
+
+}
+
+#if 0
 #ifdef WITH_VERIFY_PTR
 #  define FR_DLIST_VERIFY(_head, _type, _member) \
 do { \
@@ -105,6 +157,7 @@ do { \
 #else
 #  define FR_DLIST_VERIFY(_head, _type, _member)
 #endif
+#endif
 
 /** Convert a pointer to a member into a pointer to the parent structure.
  *
index f19674919c4d41cd45e73432137d4f947e279852..692a9a198ece85e8056f77a201f124779a771dd3 100644 (file)
@@ -300,9 +300,9 @@ struct fr_event_list {
 
        int                     kq;                     //!< instance associated with this event list.
 
-       fr_dlist_t              pre_callbacks;          //!< callbacks when we may be idle...
-       fr_dlist_t              user_callbacks;         //!< EVFILT_USER callbacks
-       fr_dlist_t              post_callbacks;         //!< post-processing callbacks
+       fr_dlist_head_t         pre_callbacks;          //!< callbacks when we may be idle...
+       fr_dlist_head_t         user_callbacks;         //!< EVFILT_USER callbacks
+       fr_dlist_head_t         post_callbacks;         //!< post-processing callbacks
 
        struct kevent           events[FR_EV_BATCH_FDS]; /* so it doesn't go on the stack every time */
 
@@ -1195,7 +1195,7 @@ uintptr_t fr_event_user_insert(fr_event_list_t *el, fr_event_user_handler_t call
        user->uctx = uctx;
        user->ident = (uintptr_t) user;
 
-       fr_dlist_insert_tail(&el->user_callbacks, &user->entry);
+       fr_dlist_insert_tail(&el->user_callbacks, user);
 
        return user->ident;;
 }
@@ -1211,19 +1211,16 @@ uintptr_t fr_event_user_insert(fr_event_list_t *el, fr_event_user_handler_t call
  */
 int fr_event_user_delete(fr_event_list_t *el, fr_event_user_handler_t callback, void *uctx)
 {
-       fr_dlist_t *entry, *next;
+       fr_event_user_t *user, *next;
 
-       for (entry = FR_DLIST_FIRST(el->user_callbacks);
-            entry != NULL;
-            entry = next) {
-               fr_event_user_t *user;
+       for (user = fr_dlist_first(&el->user_callbacks);
+            user != NULL;
+            user = next) {
+               next = fr_dlist_next(&el->user_callbacks, user);
 
-               next = FR_DLIST_NEXT(el->user_callbacks, entry);
-
-               user = fr_ptr_to_type(fr_event_user_t, entry, entry);
                if ((user->callback == callback) &&
                    (user->uctx == uctx)) {
-                       fr_dlist_remove(entry);
+                       fr_dlist_remove(&el->user_callbacks, user);
                        talloc_free(user);
                        return 0;
                }
@@ -1252,7 +1249,7 @@ int fr_event_pre_insert(fr_event_list_t *el, fr_event_status_cb_t callback, void
        pre->callback = callback;
        pre->uctx = uctx;
 
-       fr_dlist_insert_tail(&el->pre_callbacks, &pre->entry);
+       fr_dlist_insert_tail(&el->pre_callbacks, pre);
 
        return 0;
 }
@@ -1268,19 +1265,16 @@ int fr_event_pre_insert(fr_event_list_t *el, fr_event_status_cb_t callback, void
  */
 int fr_event_pre_delete(fr_event_list_t *el, fr_event_status_cb_t callback, void *uctx)
 {
-       fr_dlist_t *entry, *next;
-
-       for (entry = FR_DLIST_FIRST(el->pre_callbacks);
-            entry != NULL;
-            entry = next) {
-               fr_event_pre_t *pre;
+       fr_event_pre_t *pre, *next;
 
-               next = FR_DLIST_NEXT(el->pre_callbacks, entry);
+       for (pre = fr_dlist_first(&el->pre_callbacks);
+            pre != NULL;
+            pre = next) {
+               next = fr_dlist_next(&el->pre_callbacks, pre);
 
-               pre = fr_ptr_to_type(fr_event_pre_t, entry, entry);
                if ((pre->callback == callback) &&
                    (pre->uctx == uctx)) {
-                       fr_dlist_remove(entry);
+                       fr_dlist_remove(&el->pre_callbacks, pre);
                        talloc_free(pre);
                        return 0;
                }
@@ -1309,7 +1303,7 @@ int fr_event_post_insert(fr_event_list_t *el, fr_event_cb_t callback, void *uctx
        post->callback = callback;
        post->uctx = uctx;
 
-       fr_dlist_insert_tail(&el->post_callbacks, &post->entry);
+       fr_dlist_insert_tail(&el->post_callbacks, post);
 
        return 0;
 }
@@ -1325,19 +1319,16 @@ int fr_event_post_insert(fr_event_list_t *el, fr_event_cb_t callback, void *uctx
  */
 int fr_event_post_delete(fr_event_list_t *el, fr_event_cb_t callback, void *uctx)
 {
-       fr_dlist_t *entry, *next;
-
-       for (entry = FR_DLIST_FIRST(el->post_callbacks);
-            entry != NULL;
-            entry = next) {
-               fr_event_post_t *post;
+       fr_event_post_t *post, *next;
 
-               next = FR_DLIST_NEXT(el->post_callbacks, entry);
+       for (post = fr_dlist_first(&el->post_callbacks);
+            post != NULL;
+            post = next) {
+               next = fr_dlist_next(&el->post_callbacks, post);
 
-               post = fr_ptr_to_type(fr_event_post_t, entry, entry);
                if ((post->callback == callback) &&
                    (post->uctx == uctx)) {
-                       fr_dlist_remove(entry);
+                       fr_dlist_remove(&el->post_callbacks, post);
                        talloc_free(post);
                        return 0;
                }
@@ -1412,7 +1403,7 @@ int fr_event_corral(fr_event_list_t *el, bool wait)
 {
        struct timeval          when, *wake;
        struct timespec         ts_when, *ts_wake;
-       fr_dlist_t              *entry;
+       fr_event_pre_t          *pre;
        int                     num_fd_events, num_timer_events;
 
        el->num_fd_events = 0;
@@ -1461,12 +1452,9 @@ int fr_event_corral(fr_event_list_t *el, bool wait)
         *      application has more work to do, in which case we
         *      re-set the timeout to be instant.
         */
-       for (entry = FR_DLIST_FIRST(el->pre_callbacks);
-            entry != NULL;
-            entry = FR_DLIST_NEXT(el->pre_callbacks, entry)) {
-               fr_event_pre_t *pre;
-
-               pre = fr_ptr_to_type(fr_event_pre_t, entry, entry);
+       for (pre = fr_dlist_first(&el->pre_callbacks);
+            pre != NULL;
+            pre = fr_dlist_next(&el->pre_callbacks, pre)) {
                if (pre->callback(pre->uctx, wake) > 0) {
                        num_timer_events++;
                        wake = &when;
@@ -1514,7 +1502,7 @@ int fr_event_corral(fr_event_list_t *el, bool wait)
 void fr_event_service(fr_event_list_t *el)
 {
        int             i;
-       fr_dlist_t      *entry;
+       fr_event_post_t *post;
        struct timeval  when;
 
        if (unlikely(el->exit)) return;
@@ -1724,14 +1712,11 @@ service:
        /*
         *      Run all of the post-processing events.
         */
-       for (entry = FR_DLIST_FIRST(el->post_callbacks);
-            entry != NULL;
-            entry = FR_DLIST_NEXT(el->post_callbacks, entry)) {
-               fr_event_post_t *post;
-
+       for (post = fr_dlist_first(&el->post_callbacks);
+            post != NULL;
+            post = fr_dlist_next(&el->post_callbacks, post)) {
                when = el->now;
 
-               post = fr_ptr_to_type(fr_event_post_t, entry, entry);
                post->callback(el, &when, post->uctx);
        }
 }
@@ -1848,9 +1833,9 @@ fr_event_list_t *fr_event_list_alloc(TALLOC_CTX *ctx, fr_event_status_cb_t statu
                goto error;
        }
 
-       FR_DLIST_INIT(el->pre_callbacks);
-       FR_DLIST_INIT(el->post_callbacks);
-       FR_DLIST_INIT(el->user_callbacks);
+       fr_dlist_init(&el->pre_callbacks, offsetof(fr_event_pre_t, entry));
+       fr_dlist_init(&el->post_callbacks, offsetof(fr_event_post_t, entry));
+       fr_dlist_init(&el->user_callbacks, offsetof(fr_event_user_t, entry));
 
        if (status) (void) fr_event_pre_insert(el, status, status_uctx);
 
index 3ef92df5b68f36d9907b760918d7a8d40df3a6eb..8216ef2fa71c2f1ab86f4beaa1291d18b68582ad 100644 (file)
@@ -57,7 +57,7 @@ typedef struct fr_child_t {
        pid_t           pid;
 } fr_child_t;
 
-fr_thread_local_setup(fr_dlist_t *, fr_children) /* macro */
+fr_thread_local_setup(fr_dlist_head_t *, fr_children) /* macro */
 
 static void _fr_children_free(void *arg)
 {
@@ -102,7 +102,7 @@ pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
        char            *envp[MAX_ENVP];
        size_t          envlen = 0;
        TALLOC_CTX      *input_ctx = NULL;
-       fr_dlist_t      *list;
+       fr_dlist_head_t *list;
 
        /*
         *      Stupid array decomposition...
@@ -123,38 +123,33 @@ pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
 
        list = fr_children;
        if (!list) {
-               list = talloc_zero(NULL, fr_dlist_t);
+               list = talloc_zero(NULL, fr_dlist_head_t);
                if (!list) {
                        ERROR("Out of memory");
                        return -1;
                }
 
-               list->prev = list->next = list;
+               fr_dlist_init(list, offsetof(fr_child_t, entry));
 
                fr_thread_local_set_destructor(fr_children, _fr_children_free, list);
        } else {
-               fr_dlist_t *entry, *next;
-
-               entry = list->next;
+               fr_child_t *child, *next;
 
                /*
                 *      Clean up the children.  ALL of them.  This is
                 *      slow as heck, but correct. :(
                 */
-               while (entry != list) {
+               for (child = fr_dlist_first(fr_children);
+                    child != NULL;
+                    child = next) {
                        int status;
-                       fr_child_t *child;
-
-                       next = entry->next;
 
-                       child = fr_ptr_to_type(fr_child_t, entry, entry);
+                       next = fr_dlist_next(fr_children, child);
                        pid = waitpid(child->pid, &status, WNOHANG);
                        if (pid != 0) {
-                               fr_dlist_remove(entry);
+                               fr_dlist_remove(fr_children, child);
                                talloc_free(child);
                        }
-
-                       entry = next;
                }
        }
 
@@ -378,7 +373,7 @@ pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
                fr_child_t *child;
 
                MEM(child = talloc_zero(fr_children, fr_child_t));
-               fr_dlist_insert_tail(fr_children, &child->entry);
+               fr_dlist_insert_tail(fr_children, child);
                child->pid = pid;
        }
 
index 7344e7ad5ea5a1f100ab38ea5039cf16cde6d6e3..4621ec35950acbee973359279dc86a947e15a878 100644 (file)
@@ -95,7 +95,7 @@ typedef struct state_entry {
 
        uint64_t                seq_start;                      //!< Number of first request in this sequence.
        time_t                  cleanup;                        //!< When this entry should be cleaned up.
-       fr_dlist_t              list;                           //!< Entry in the list of things to expire.
+       fr_dlist_t              entry;                          //!< Entry in the list of things to expire.
 
        int                     tries;
 
@@ -114,7 +114,7 @@ struct fr_state_tree_t {
                                                                //!< timeout.
        uint32_t                max_sessions;                   //!< Maximum number of sessions we track.
        rbtree_t                *tree;                          //!< rbtree used to lookup state value.
-       fr_dlist_t              to_expire;                      //!< Linked list of entries to free.
+       fr_dlist_head_t         to_expire;                      //!< Linked list of entries to free.
 
        uint32_t                timeout;                        //!< How long to wait before cleaning up state entires.
 
@@ -146,16 +146,13 @@ static int state_entry_cmp(void const *one, void const *two)
  */
 static int _state_tree_free(fr_state_tree_t *state)
 {
-       fr_dlist_t              *next;
+       fr_state_entry_t *entry;
 
        if (main_config->spawn_workers) pthread_mutex_destroy(&state->mutex);
 
        DEBUG4("Freeing state tree %p", state);
 
-       while ((next = FR_DLIST_FIRST(state->to_expire))) {
-               fr_state_entry_t        *entry;
-
-               entry = fr_ptr_to_type(fr_state_entry_t, list, next);
+       while ((entry = fr_dlist_first(&state->to_expire))) {
                state_entry_unlink(state, entry);
                talloc_free(entry);
        }
@@ -205,7 +202,7 @@ fr_state_tree_t *fr_state_tree_init(TALLOC_CTX *ctx, fr_dict_attr_t const *da, b
                return NULL;
        }
 
-       FR_DLIST_INIT(state->to_expire);
+       fr_dlist_init(&state->to_expire, offsetof(fr_state_entry_t, entry));
 
        /*
         *      We need to do controlled freeing of the
@@ -236,7 +233,7 @@ static void state_entry_unlink(fr_state_tree_t *state, fr_state_entry_t *entry)
         */
        (void) talloc_get_type_abort(entry, fr_state_entry_t);
 
-       fr_dlist_remove(&entry->list);
+       fr_dlist_remove(&state->to_expire, entry);
 
        rbtree_deletebydata(state->tree, entry);
 
@@ -269,12 +266,6 @@ static int _state_entry_free(fr_state_entry_t *entry)
         *      so we know it'll be cleaned up.
         */
        if (entry->data) (void)fr_cond_assert(request_data_verify_parent(entry->ctx, entry->data));
-
-       /*
-        *      Verify the state entry is no longer linked
-        */
-       rad_assert(entry->list.prev == &entry->list);
-       rad_assert(entry->list.next == &entry->list);
 #endif
 
        /*
@@ -298,24 +289,24 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, REQUEST *req
        uint32_t                x;
        time_t                  now = time(NULL);
        VALUE_PAIR              *vp;
-       fr_state_entry_t        *entry;
+       fr_state_entry_t        *entry, *next;
 
        uint8_t                 old_state[sizeof(old->state)];
        int                     old_tries = 0;
        uint64_t                timed_out = 0;
        bool                    too_many = false;
-       fr_dlist_t              to_free, *next;
+       fr_dlist_head_t         to_free;
 
-       FR_DLIST_INIT(to_free);
+       fr_dlist_init(&to_free, offsetof(fr_state_entry_t, entry));
 
        /*
         *      Clean up old entries.
         */
-       next = FR_DLIST_FIRST(state->to_expire);
-       while (next) {
-               entry = fr_ptr_to_type(fr_state_entry_t, list, next);
+       for (entry = fr_dlist_first(&state->to_expire);
+            entry != NULL;
+            entry = next) {
                (void)talloc_get_type_abort(entry, fr_state_entry_t);   /* Allow examination */
-               next = FR_DLIST_NEXT(state->to_expire, next);           /* Advance *before* potential unlinking */
+               next = fr_dlist_next(&state->to_expire, entry);         /* Advance *before* potential unlinking */
 
                if (entry == old) continue;
 
@@ -324,7 +315,7 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, REQUEST *req
                 */
                if (entry->cleanup < now) {
                        state_entry_unlink(state, entry);
-                       fr_dlist_insert_tail(&to_free, &entry->list);
+                       fr_dlist_insert_tail(&to_free, entry);
                        timed_out++;
                        continue;
                }
@@ -353,7 +344,7 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, REQUEST *req
                 */
                if (!old->data) {
                        state_entry_unlink(state, old);
-                       fr_dlist_insert_tail(&to_free, &old->list);
+                       fr_dlist_insert_tail(&to_free, old);
                }
        }
        PTHREAD_MUTEX_UNLOCK(&state->mutex);
@@ -370,9 +361,9 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, REQUEST *req
         *      be freed also, and it may have complex destructors associated
         *      with it.
         */
-       while ((next = FR_DLIST_FIRST(to_free)) != NULL) {
-               fr_dlist_remove(next);
-               talloc_free(fr_ptr_to_type(fr_state_entry_t, list, next));
+       while ((entry = fr_dlist_first(&to_free)) != NULL) {
+               fr_dlist_remove(&to_free, entry);
+               talloc_free(entry);
        }
 
        /*
@@ -507,7 +498,7 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, REQUEST *req
         *      Link it to the end of the list, which is implicitely
         *      ordered by cleanup time.
         */
-       fr_dlist_insert_tail(&state->to_expire, &entry->list);
+       fr_dlist_insert_tail(&state->to_expire, entry);
 
        return entry;
 }
index 69fc8319489d3b1db66faf483ee3ac5a793083fa..4586ed3dd3251c954b60999852d4cc9d6d25847f 100644 (file)
@@ -99,7 +99,7 @@ typedef struct proto_detail_work_t {
        uint32_t                        max_outstanding;        //!< number of packets to run in parallel
        uint32_t                        outstanding;            //!< number of currently outstanding records;
 
-       fr_dlist_t                      list;                   //!< for retransmissions
+       fr_dlist_head_t                 list;                   //!< for retransmissions
 
        bool                            vnode;                  //!< are we the vnode instance,
                                                                //!< or the filename_work instance?
index 0aab049790baddc0ef1a34fdb26499277fb1398e..6d7b7cd9e2f8fa3c4f2fbfec46c5f5f2c7936a8d 100644 (file)
@@ -146,7 +146,6 @@ static ssize_t mod_read(void *instance, void **packet_ctx, fr_time_t **recv_time
        uint8_t                         *partial, *end, *next, *p, *record_end;
        uint8_t                         *stopped_search;
        off_t                           done_offset;
-       fr_dlist_t                      *entry;
 
        rad_assert(*leftover < buffer_len);
        rad_assert(inst->fd >= 0);
@@ -156,11 +155,9 @@ static ssize_t mod_read(void *instance, void **packet_ctx, fr_time_t **recv_time
         *      Process retransmissions before anything else in the
         *      file.
         */
-       entry = FR_DLIST_FIRST(inst->list);
-       if (entry) {
-               track = fr_ptr_to_type(fr_detail_entry_t, entry, entry);
-
-               fr_dlist_remove(&track->entry);
+       track = fr_dlist_first(&inst->list);
+       if (track) {
+               fr_dlist_remove(&inst->list, track);
 
                /*
                 *      Don't over-write "leftover" bytes!
@@ -534,7 +531,7 @@ static void work_retransmit(UNUSED fr_event_list_t *el, UNUSED struct timeval *n
        DEBUG("%s - retransmitting packet %d", inst->name, track->id);
        track->count++;
 
-       fr_dlist_insert_tail(&inst->list, &track->entry);
+       fr_dlist_insert_tail(&inst->list, &track);
 
        if (inst->paused && (inst->outstanding < inst->max_outstanding)) {
                (void) fr_event_filter_update(inst->el, inst->fd, FR_EVENT_FILTER_IO, resume_read);
@@ -817,7 +814,7 @@ static int mod_instantiate(void *instance, UNUSED CONF_SECTION *cs)
        proto_detail_work_t *inst = talloc_get_type_abort(instance, proto_detail_work_t);
        RADCLIENT *client;
 
-       FR_DLIST_INIT(inst->list);
+       fr_dlist_init(&inst->list, offsetof(fr_detail_entry_t, entry));
 
        client = inst->client = talloc_zero(inst, RADCLIENT);
        if (!inst->client) return 0;
index 687c1aa6d162830025703bdadede1c0856319ac6..bbad3f34e3c69474a5ebdecd41666129cbb6e61b 100644 (file)
@@ -386,7 +386,7 @@ static int status_check_update_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED v
  */
 static int mod_link_free(rlm_radius_link_t *link)
 {
-       fr_dlist_remove(&link->entry);
+       fr_dlist_remove(&link->t->running, link);
 
        /*
         *      Free the child's request io context.  That will call
@@ -564,7 +564,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_process(void *instance, void *thread, RE
         */
        radius_fixups(inst, request);
 
-       fr_dlist_insert_tail(&t->running, &link->entry);
+       fr_dlist_insert_tail(&t->running, link);
        talloc_set_destructor(link, mod_link_free);
 
        /*
@@ -819,7 +819,7 @@ static int mod_thread_instantiate(UNUSED CONF_SECTION const *cs, void *instance,
        t->inst = instance;
        t->el = el;
 
-       FR_DLIST_INIT(t->running);
+       fr_dlist_init(&t->running, offsetof(rlm_radius_link_t, entry));
 
        /*
         *      Allocate thread-specific data.  The connections should
@@ -849,7 +849,6 @@ static int mod_thread_detach(fr_event_list_t *el, void *thread)
 {
        rlm_radius_thread_t *t = talloc_get_type_abort(thread, rlm_radius_thread_t);
        rlm_radius_t const *inst = t->inst;
-       fr_dlist_t *entry;
 
        /*
         *      Tell the submodule to shut down all of its
@@ -867,8 +866,7 @@ static int mod_thread_detach(fr_event_list_t *el, void *thread)
         *      marked DONE, and (in an ideal world) resumed / cleaned
         *      up before this memory is freed.
         */
-       entry = FR_DLIST_FIRST(t->running);
-       if (entry != NULL) {
+       if (fr_dlist_first(&t->running) != NULL) {
                ERROR("Module still has running requests!");
                return -1;
        }
index 337ad265f54c352beb0dd6fdeb6685d3cfd8e681..7c09145f5a13c1980aaa0b8fc521658c57fb6404 100644 (file)
@@ -127,7 +127,7 @@ typedef struct rlm_radius_thread_t {
        rlm_radius_t const      *inst;                  //!< Instance of the module.
        fr_event_list_t         *el;                    //!< This thread's event list.
 
-       fr_dlist_t              running;                //!< running requests
+       fr_dlist_head_t         running;                //!< running requests
 
        void                    *thread_io_ctx;         //!< thread context for the IO submodule
 } rlm_radius_thread_t;
index 1949ef9d99a2856f0271cab0830a0177a8197efb..2f660810b16a6baf97ad7bdc92a239e48df4f876 100644 (file)
@@ -71,10 +71,10 @@ typedef struct rlm_radius_udp_thread_t {
        fr_heap_t               *queued;                //!< Queued requests for some new connection.
 
        fr_heap_t               *active;                //!< Active connections.
-       fr_dlist_t              blocked;                //!< blocked connections, waiting for writable
-       fr_dlist_t              full;                   //!< Full connections.
-       fr_dlist_t              zombie;                 //!< Zombie connections.
-       fr_dlist_t              opening;                //!< Opening connections.
+       fr_dlist_head_t         blocked;                //!< blocked connections, waiting for writable
+       fr_dlist_head_t         full;                   //!< Full connections.
+       fr_dlist_head_t         zombie;                 //!< Zombie connections.
+       fr_dlist_head_t         opening;                //!< Opening connections.
 } rlm_radius_udp_thread_t;
 
 typedef enum rlm_radius_udp_connection_state_t {
@@ -110,7 +110,7 @@ typedef struct rlm_radius_udp_connection_t {
        fr_event_timer_t const  *zombie_ev;             //!< Zombie timeout.
        struct timeval          zombie_start;           //!< When the zombie period started.
 
-       fr_dlist_t              sent;                   //!< List of sent packets.
+       fr_dlist_head_t         sent;                   //!< List of sent packets.
 
        uint32_t                max_packet_size;        //!< Our max packet size. may be different from the parent.
        int                     fd;                     //!< File descriptor.
@@ -299,7 +299,7 @@ static void conn_check_idle(rlm_radius_udp_connection_t *c)
                /*
                 *      No outstanding packets, we're idle.
                 */
-               if (FR_DLIST_FIRST(c->sent) == NULL) {
+               if (fr_dlist_first(&c->sent) == NULL) {
                        break;
                }
 
@@ -494,7 +494,7 @@ static void state_transition(rlm_radius_udp_request_t *u, rlm_radius_request_sta
                rad_assert(u->rr != NULL);
                rad_assert(u->c != NULL);
                (void) rr_track_delete(u->c->id, u->rr);
-               fr_dlist_remove(&u->entry);
+               fr_dlist_remove(&u->c->sent, u);
                u->rr = NULL;
                u->c = NULL;
                break;
@@ -520,7 +520,7 @@ static void state_transition(rlm_radius_udp_request_t *u, rlm_radius_request_sta
        case PACKET_STATE_SENT:
                rad_assert(u->rr != NULL);
                rad_assert(u->c != NULL);
-               fr_dlist_insert_tail(&u->c->sent, &u->entry);
+               fr_dlist_insert_tail(&u->c->sent, u);
                break;
 
        case PACKET_STATE_RESUMABLE:
@@ -695,7 +695,7 @@ static void conn_transition(rlm_radius_udp_connection_t *c, rlm_radius_udp_conne
        case CONN_OPENING:
        case CONN_FULL:
        case CONN_BLOCKED:
-               fr_dlist_remove(&c->entry);
+               fr_dlist_remove(&c->thread->blocked, c); /* we only need 'offset' from the list */
                break;
 
        case CONN_ACTIVE:
@@ -712,7 +712,7 @@ static void conn_transition(rlm_radius_udp_connection_t *c, rlm_radius_udp_conne
                 */
                if (state == CONN_BLOCKED) return;
 
-               fr_dlist_remove(&c->entry);
+               fr_dlist_remove(&c->thread->blocked, c);
                if (c->zombie_ev) (void) fr_event_timer_delete(c->thread->el, &c->zombie_ev);
                break;
        }
@@ -726,7 +726,7 @@ static void conn_transition(rlm_radius_udp_connection_t *c, rlm_radius_udp_conne
                break;
 
        case CONN_OPENING:
-               fr_dlist_insert_head(&c->thread->opening, &c->entry);
+               fr_dlist_insert_head(&c->thread->opening, c);
                break;
 
        case CONN_ACTIVE:
@@ -738,19 +738,19 @@ static void conn_transition(rlm_radius_udp_connection_t *c, rlm_radius_udp_conne
        case CONN_BLOCKED:
                if (c->idle_ev) (void) fr_event_timer_delete(c->thread->el, &c->idle_ev);
 
-               fr_dlist_insert_head(&c->thread->blocked, &c->entry);
+               fr_dlist_insert_head(&c->thread->blocked, c);
                break;
 
        case CONN_FULL:
                if (c->idle_ev) (void) fr_event_timer_delete(c->thread->el, &c->idle_ev);
 
-               fr_dlist_insert_head(&c->thread->full, &c->entry);
+               fr_dlist_insert_head(&c->thread->full, c);
                break;
 
        case CONN_ZOMBIE:
                if (c->idle_ev) (void) fr_event_timer_delete(c->thread->el, &c->idle_ev);
 
-               fr_dlist_insert_head(&c->thread->zombie, &c->entry);
+               fr_dlist_insert_head(&c->thread->zombie, c);
 
                gettimeofday(&when, NULL);
                c->zombie_start = when;
@@ -1974,13 +1974,13 @@ static fr_connection_state_t _conn_failed(UNUSED int fd, fr_connection_state_t s
         *      timer events before reconnecting.
         */
        if (state == FR_CONNECTION_STATE_CONNECTED) {
-               fr_dlist_t *entry;
+               rlm_radius_udp_request_t *u;
 
                /*
                 *      Reset the Status-Server checks.
                 */
                if (c->status_u) {
-                       rlm_radius_udp_request_t *u = c->status_u;
+                       u = c->status_u;
 
                        if (u->timer.ev) (void) fr_event_timer_delete(c->thread->el, &u->timer.ev);
 
@@ -2002,10 +2002,7 @@ static fr_connection_state_t _conn_failed(UNUSED int fd, fr_connection_state_t s
                /*
                 *      Move "sent" packets back to the thread queue,
                 */
-               while ((entry = FR_DLIST_FIRST(c->sent)) != NULL) {
-                       rlm_radius_udp_request_t *u;
-
-                       u = fr_ptr_to_type(rlm_radius_udp_request_t, entry, entry);
+               while ((u = fr_dlist_first(&c->sent)) != NULL) {
                        state_transition(u, PACKET_STATE_THREAD);
                }
        }
@@ -2047,7 +2044,7 @@ static fr_connection_state_t _conn_open(UNUSED fr_event_list_t *el, int fd, void
 
        rad_assert(c->zombie_ev == NULL);
        memset(&c->zombie_start, 0, sizeof(c->zombie_start));
-       FR_DLIST_INIT(c->sent);
+       fr_dlist_init(&c->sent, offsetof(rlm_radius_udp_request_t, entry));
 
        /*
         *      Status-Server checks.  Manually build the packet, and
@@ -2106,14 +2103,12 @@ static fr_connection_state_t _conn_open(UNUSED fr_event_list_t *el, int fd, void
                 *      Initialize the link.  Note that we don't set
                 *      destructors.
                 */
-               FR_DLIST_INIT(link->entry);
                link->request = request;
                link->request_io_ctx = u;
 
                /*
                 *      Unitialize the UDP link.
                 */
-               FR_DLIST_INIT(u->entry);
                u->code = c->inst->parent->status_check;
                request->packet->code = u->code;
                u->c = c;
@@ -2230,7 +2225,6 @@ static fr_connection_state_t _conn_init(int *fd_out, void *uctx)
  */
 static int _conn_free(rlm_radius_udp_connection_t *c)
 {
-       fr_dlist_t                      *entry;
        rlm_radius_udp_request_t        *u;
        rlm_radius_udp_thread_t         *t = talloc_get_type_abort(c->thread, rlm_radius_udp_thread_t);
 
@@ -2256,9 +2250,7 @@ static int _conn_free(rlm_radius_udp_connection_t *c)
        /*
         *      Move "sent" packets back to the main thread queue
         */
-       while ((entry = FR_DLIST_FIRST(c->sent)) != NULL) {
-               u = fr_ptr_to_type(rlm_radius_udp_request_t, entry, entry);
-
+       while ((u = fr_dlist_first(&c->sent)) != NULL) {
                rad_assert(u->state == PACKET_STATE_SENT);
                rad_assert(u->c == c);
 
@@ -2283,7 +2275,7 @@ static int _conn_free(rlm_radius_udp_connection_t *c)
        case CONN_OPENING:
        case CONN_FULL:
        case CONN_ZOMBIE:
-               fr_dlist_remove(&c->entry);
+               fr_dlist_remove(&c->thread->blocked, c);
                break;
 
        case CONN_ACTIVE:
@@ -2341,7 +2333,7 @@ static void conn_alloc(rlm_radius_udp_t *inst, rlm_radius_udp_thread_t *t)
                talloc_free(c);
                return;
        }
-       FR_DLIST_INIT(c->sent);
+       fr_dlist_init(&c->sent, offsetof(rlm_radius_udp_request_t, entry));
 
        c->conn = fr_connection_alloc(c, t->el, &inst->parent->connection_timeout, &inst->parent->reconnection_delay,
                                      _conn_init,
@@ -2411,7 +2403,7 @@ static rlm_rcode_t mod_push(void *instance, REQUEST *request, rlm_radius_link_t
        u->thread = t;
        u->heap_id = -1;
        u->timer.retry = &inst->parent->retry[u->code];
-       FR_DLIST_INIT(u->entry);
+       fr_dlist_entry_init(&u->entry);
 
        talloc_set_destructor(u, udp_request_free);
 
@@ -2457,13 +2449,10 @@ static rlm_rcode_t mod_push(void *instance, REQUEST *request, rlm_radius_link_t
         */
        c = fr_heap_peek(t->active);
        if (!c) {
-               fr_dlist_t *entry;
-
                /*
                 *      Only open one new connection at a time.
                 */
-               entry = FR_DLIST_FIRST(t->opening);
-               if (!entry) conn_alloc(inst, t);
+               if (!fr_dlist_first(&t->opening)) conn_alloc(inst, t);
 
                /*
                 *      Add the request to the backlog.  It will be
@@ -2626,10 +2615,10 @@ static int mod_thread_instantiate(UNUSED CONF_SECTION const *cs, void *instance,
        t->el = el;
 
        t->queued = fr_heap_talloc_create(t, queue_cmp, rlm_radius_udp_request_t, heap_id);
-       FR_DLIST_INIT(t->blocked);
-       FR_DLIST_INIT(t->full);
-       FR_DLIST_INIT(t->zombie);
-       FR_DLIST_INIT(t->opening);
+       fr_dlist_init(&t->blocked, offsetof(rlm_radius_udp_connection_t, entry));
+       fr_dlist_init(&t->full, offsetof(rlm_radius_udp_connection_t, entry));
+       fr_dlist_init(&t->zombie, offsetof(rlm_radius_udp_connection_t, entry));
+       fr_dlist_init(&t->opening, offsetof(rlm_radius_udp_connection_t, entry));
 
        t->active = fr_heap_talloc_create(t, conn_cmp, rlm_radius_udp_connection_t, heap_id);
 
@@ -2644,7 +2633,6 @@ static int mod_thread_instantiate(UNUSED CONF_SECTION const *cs, void *instance,
 static int mod_thread_detach(UNUSED fr_event_list_t *el, void *thread)
 {
        rlm_radius_udp_thread_t *t = talloc_get_type_abort(thread, rlm_radius_udp_thread_t);
-       fr_dlist_t *entry;
 
        if (fr_heap_num_elements(t->queued) != 0) {
                ERROR("There are still queued requests");
@@ -2656,8 +2644,7 @@ static int mod_thread_detach(UNUSED fr_event_list_t *el, void *thread)
         */
        talloc_free_children(t);
 
-       entry = FR_DLIST_FIRST(t->opening);
-       if (entry != NULL) {
+       if (fr_dlist_first(&t->opening) != NULL) {
                ERROR("There are still partially open sockets");
                return -1;
        }
index e3a63a71d92d5b1ca2724c089b787b158c83225a..84e82f38a54db8468cad0d57bde4c3f2e9fde2fb 100644 (file)
@@ -68,11 +68,11 @@ rlm_radius_id_t *rr_track_create(TALLOC_CTX *ctx)
        id = talloc_zero(ctx, rlm_radius_id_t);
        if (!id) return NULL;
 
-       FR_DLIST_INIT(id->free_list);
+       fr_dlist_init(&id->free_list, offsetof(rlm_radius_request_t, entry));
 
        for (i = 0; i < 256; i++) {
                id->id[i].id = i;
-               fr_dlist_insert_tail(&id->free_list, &id->id[i].entry);
+               fr_dlist_insert_tail(&id->free_list, &id->id[i]);
                id->num_free++;
        }
 
@@ -109,22 +109,19 @@ static int rr_cmp(void const *one, void const *two)
 rlm_radius_request_t *rr_track_alloc(rlm_radius_id_t *id, REQUEST *request, int code, rlm_radius_link_t *link,
                                     rlm_radius_retransmit_t *timer)
 {
-       fr_dlist_t *entry;
        rlm_radius_request_t *rr;
 
 retry:
-       entry = FR_DLIST_FIRST(id->free_list);
-       if (entry) {
+       rr = fr_dlist_first(&id->free_list);
+       if (rr) {
                rad_assert(id->num_free > 0);
 
-               rr = fr_ptr_to_type(rlm_radius_request_t, entry, entry);
-
                rad_assert(rr->request == NULL);
 
                /*
                 *      Mark it as used, and remove it from the free list.
                 */
-               fr_dlist_remove(&rr->entry);
+               fr_dlist_remove(&id->free_list, rr);
                id->num_free--;
 
                /*
@@ -167,7 +164,6 @@ retry:
         *      Allocate a new one, and insert it into the appropriate subtree.
         */
        rr = talloc_zero(id, rlm_radius_request_t);
-       FR_DLIST_INIT(rr->entry);
        rr->id = id->next_id;
 
 done:
@@ -284,7 +280,7 @@ int rr_track_delete(rlm_radius_id_t *id, rlm_radius_request_t *rr)
         *      Otherwise put it back on the free list.
         */
 done:
-       fr_dlist_insert_tail(&id->free_list, &rr->entry);
+       fr_dlist_insert_tail(&id->free_list, rr);
        id->num_free++;
 
        return 0;
index 4766b063338dbd91959a153bd126a1ea4d899836..17a3b96e47f8b7fd93034b3d9b2c4a7760e31885 100644 (file)
@@ -58,7 +58,7 @@ typedef struct rlm_radius_id_t {
        int                     num_requests;   //!< number of requests in the allocation
        int                     num_free;       //!< number of entries in the free list
 
-       fr_dlist_t              free_list;      //!< so we allocate by least recently used
+       fr_dlist_head_t         free_list;      //!< so we allocate by least recently used
 
        bool                    use_authenticator; //!< whether to use the request authenticator as an ID
        int                     next_id;        //!< next ID to allocate
index 17dd77e0e30ff7820827ebe6637fe14943381628..b0995d690045e1b2fe45c8bf405d5b4354942033 100644 (file)
@@ -54,7 +54,7 @@ typedef struct rlm_stats_t {
        fr_dict_attr_t const    *type_da;                       //!< FreeRADIUS-Stats4-Type
        fr_dict_attr_t const    *ipv4_da;                       //!< FreeRADIUS-Stats4-IPv4-Address
        fr_dict_attr_t const    *ipv6_da;                       //!< FreeRADIUS-Stats4-IPv6-Address
-       fr_dlist_t              entry;                          //!< for threads to know about each other
+       fr_dlist_head_t         list;                           //!< for threads to know about each other
 
        uint64_t                stats[FR_MAX_PACKET_CODE];
 } rlm_stats_t;
@@ -116,7 +116,6 @@ static void coalesce(uint64_t final_stats[FR_MAX_PACKET_CODE], rlm_stats_thread_
                     rlm_stats_data_t *mydata)
 {
        rlm_stats_data_t *stats;
-       fr_dlist_t *entry;
        rlm_stats_thread_t *other;
 #ifdef HAVE_PTHREAD_H
        pthread_mutex_t *mutex;
@@ -141,10 +140,9 @@ static void coalesce(uint64_t final_stats[FR_MAX_PACKET_CODE], rlm_stats_thread_
         *      Loop over all of the other thread instances, locking
         *      them, and adding their statistics in.
         */
-       for (entry = FR_DLIST_FIRST(t->inst->entry);
-            entry != NULL;
-            entry = FR_DLIST_NEXT(t->inst->entry, entry)) {
-               other = fr_ptr_to_type(rlm_stats_thread_t, entry, entry);
+       for (other = fr_dlist_first(&t->inst->list);
+            other != NULL;
+            other = fr_dlist_next(&t->inst->list, other)) {
                int i;
 
                if (other == t) continue;
@@ -389,7 +387,7 @@ static int mod_thread_instantiate(UNUSED CONF_SECTION const *cs, void *instance,
        t->dst = rbtree_talloc_create(t, data_cmp, rlm_stats_data_t, NULL, RBTREE_FLAG_NONE);
 
        PTHREAD_MUTEX_LOCK(&inst->mutex);
-       fr_dlist_insert_head(&inst->entry, &t->entry);
+       fr_dlist_insert_head(&inst->list, t);
        PTHREAD_MUTEX_UNLOCK(&inst->mutex);
 
        return 0;
@@ -409,7 +407,7 @@ static int mod_thread_detach(UNUSED fr_event_list_t *el, void *thread)
        for (i = 0; i < FR_MAX_PACKET_CODE; i++) {
                inst->stats[i] += t->stats[i];
        }
-       fr_dlist_remove(&t->entry);
+       fr_dlist_remove(&inst->list, t);
        PTHREAD_MUTEX_UNLOCK(&inst->mutex);
 
        return 0;
@@ -423,7 +421,7 @@ static int mod_instantiate(void *instance, UNUSED CONF_SECTION *conf)
        pthread_mutex_init(&inst->mutex, NULL);
 #endif
 
-       FR_DLIST_INIT(inst->entry);
+       fr_dlist_init(&inst->list, offsetof(rlm_stats_thread_t, entry));
 
        return 0;
 }
index cf1b3a5bda492058b4e4fdf4d2232cca174bdac5..ea0eaaf48fa92f352048b07cb1722df7a9800397 100644 (file)
@@ -529,7 +529,7 @@ static REQUEST *unlang_child_alloc(REQUEST *request, unlang_t *instruction, rlm_
         *      Instead, all of it is done in the context of the
         *      parent.
         */
-       FR_DLIST_INIT(child->async->tracking.list);
+       fr_dlist_init(&child->async->tracking.list, 0);
 
        /*
         *      create {...} creates an empty copy.