]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
move thread create && wait to common functions
authorAlan T. DeKok <aland@freeradius.org>
Sun, 15 Mar 2026 15:30:18 +0000 (11:30 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 15 Mar 2026 18:30:38 +0000 (14:30 -0400)
src/bin/radmin.c
src/bin/unit_test_module.c
src/lib/io/coord.c
src/lib/io/schedule.c
src/lib/io/schedule.h
src/lib/io/thread.c
src/lib/io/thread.h
src/modules/rlm_sigtran/event.c

index b57e46beb9fd09add4c35ca3cbbdc1b9e929ffce..b147255506c8d0e5217091d51bdfb675fa43907c 100644 (file)
@@ -25,7 +25,7 @@
  */
 RCSID("$Id$")
 
-#include <freeradius-devel/io/schedule.h>
+#include <freeradius-devel/io/thread.h>
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/server/radmin.h>
@@ -1134,7 +1134,7 @@ int fr_radmin_start(main_config_t *config, bool cli, int std_fd[static 3])
         *      won't go into la-la-land.  They might find unfinished
         *      commands, but they don't crash.
         */
-       if (fr_schedule_pthread_create(&cli_pthread_id, fr_radmin, NULL) < 0) {
+       if (fr_thread_create(&cli_pthread_id, fr_radmin, NULL) < 0) {
                PERROR("Failed creating radmin thread");
                return -1;
        }
index 92d49bd7d18ce1fe7222649c5f8547ac584524cf..48b8dff55fdbfb5bc983aab8836a86f0f972170d 100644 (file)
@@ -1027,11 +1027,6 @@ int main(int argc, char *argv[])
                EXIT_WITH_FAILURE;
        }
 
-       if (unlang_thread_instantiate(thread_ctx) < 0) {
-               fr_perror("%s", config->name);
-               EXIT_WITH_FAILURE;
-       }
-
        /*
         *  Set the panic action (if required)
         */
index 8070ee6188f266971d35a353fba533848efac21b..3998f82b50968335669add88c817d1b4a8d86c29 100644 (file)
@@ -506,7 +506,7 @@ int fr_coord_start(uint32_t num_workers, fr_sem_t *sem)
                sc->max_workers = num_workers;
                sc->sem = sem;
 
-               if (fr_schedule_pthread_create(&sc->pthread_id, fr_coordinate_thread, sc) < 0) {
+               if (fr_thread_create(&sc->pthread_id, fr_coordinate_thread, sc) < 0) {
                        talloc_free(sc);
                        PERROR("Failed creating coordinator %s", coord_reg->name);
                        return -1;
@@ -516,12 +516,9 @@ int fr_coord_start(uint32_t num_workers, fr_sem_t *sem)
        }
 
        /*
-        *      See if all the coordinators have started.
+        *      Wait for all the coordinators to start.
         */
-       fr_dlist_foreach(coord_threads, fr_schedule_coord_t, sc) {
-               DEBUG3("Waiting for semaphore from coordinator %s", sc->coord_reg->name);
-               SEM_WAIT_INTR(sem);
-       }
+       fr_thread_wait(sem, fr_dlist_num_elements(coord_threads));
 
        /*
         *      Insert the coordinators in the tree
index d509e16be77445e1f6ab0dbb493204903de563a6..0d89710213e6d3580a424e94f39ea00167afe11d 100644 (file)
@@ -314,45 +314,6 @@ fail:
        return NULL;
 }
 
-/** Creates a new thread using our standard set of options
- *
- * New threads are:
- * - Joinable, i.e. you can call pthread_join on them to confirm they've exited
- * - Immune to catchable signals.
- *
- * @param[out] thread          handled that was created by pthread_create.
- * @param[in] func             entry point for the thread.
- * @param[in] arg              Argument to pass to func.
- * @return
- *     - 0 on success.
- *     - -1 on failure.
- */
-int fr_schedule_pthread_create(pthread_t *thread, void *(*func)(void *), void *arg)
-{
-       pthread_attr_t                  attr;
-       int                             ret;
-
-       /*
-        *      Set the thread to wait around after it's exited
-        *      so it can be joined.  This is more of a useful
-        *      mechanism for the parent to determine if all
-        *      the threads have exited so it can continue with
-        *      a graceful shutdown.
-        */
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
-       ret = pthread_create(thread, &attr, func, arg);
-       if (ret != 0) {
-               pthread_attr_destroy(&attr);
-               fr_strerror_printf("Failed creating thread: %s", fr_syserror(ret));
-               return -1;
-       }
-       pthread_attr_destroy(&attr);
-
-       return 0;
-}
-
 /** Create a scheduler and spawn the child threads.
  *
  * @param[in] ctx                              talloc context.
@@ -544,7 +505,7 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el,
                sn->sc = sc;
                sn->status = FR_CHILD_INITIALIZING;
 
-               if (fr_schedule_pthread_create(&sn->pthread_id, fr_schedule_network_thread, sn) < 0) {
+               if (fr_thread_create(&sn->pthread_id, fr_schedule_network_thread, sn) < 0) {
                        talloc_free(sn);
                        PERROR("Failed creating network %u", i);
                        break;
@@ -558,11 +519,7 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el,
         *      they've started, OR there's been a problem and they
         *      can't start.
         */
-       for (i = 0; i < (unsigned int)fr_dlist_num_elements(&sc->networks); i++) {
-               DEBUG3("Waiting for semaphore from network %u/%u",
-                      i + 1, (unsigned int)fr_dlist_num_elements(&sc->networks));
-               SEM_WAIT_INTR(sc->network_sem);
-       }
+       fr_thread_wait(sc->network_sem, fr_dlist_num_elements(&sc->networks));
 
        /*
         *      See if all of the networks have started.
@@ -613,7 +570,7 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el,
                sw->sc = sc;
                sw->status = FR_CHILD_INITIALIZING;
 
-               if (fr_schedule_pthread_create(&sw->pthread_id, fr_schedule_worker_thread, sw) < 0) {
+               if (fr_thread_create(&sw->pthread_id, fr_schedule_worker_thread, sw) < 0) {
                        talloc_free(sw);
                        PERROR("Failed creating worker %u", i);
                        break;
@@ -627,11 +584,7 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el,
         *      they've started, OR there's been a problem and they
         *      can't start.
         */
-       for (i = 0; i < (unsigned int)fr_dlist_num_elements(&sc->workers); i++) {
-               DEBUG3("Waiting for semaphore from worker %u/%u",
-                      i + 1, (unsigned int)fr_dlist_num_elements(&sc->workers));
-               SEM_WAIT_INTR(sc->worker_sem);
-       }
+       fr_thread_wait(sc->worker_sem, fr_dlist_num_elements(&sc->workers));
 
        /*
         *      See if all of the workers have started.
index a5c90f3d428f68648882bc93a45f4bb43329722b..26bee18a23ab63f3ec40066130879951d5c9f0e0 100644 (file)
@@ -75,7 +75,6 @@ typedef struct {
 
 int                    fr_schedule_worker_id(void);
 
-int                    fr_schedule_pthread_create(pthread_t *thread, void *(*func)(void *), void *arg);
 fr_schedule_t          *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el, fr_log_t *log, fr_log_lvl_t lvl,
                                            fr_schedule_thread_instantiate_t worker_thread_instantiate,
                                            fr_schedule_thread_detach_t worker_thread_detach,
index 3bbe20e29f771241ad130df16505b8255d3e253c..997fc7463b9d957afb627a68e3d8374f1172972b 100644 (file)
@@ -34,6 +34,54 @@ RCSID("$Id$")
 
 #include <signal.h>
 
+/** Create a joinable thread
+ *
+ * @param[out] thread          handle that was created by pthread_create.
+ * @param[in] func             entry point for the thread.
+ * @param[in] arg              Argument to pass to func.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int fr_thread_create(pthread_t *thread, fr_thread_entry_t func, void *arg)
+{
+       pthread_attr_t                  attr;
+       int                             rcode;
+
+       /*
+        *      Set the thread to wait around after it's exited so it
+        *      can be joined.  This is more of a useful mechanism for
+        *      the parent to determine if all the threads have exited
+        *      so it can continue with a graceful shutdown.
+        */
+       pthread_attr_init(&attr);
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+       rcode = pthread_create(thread, &attr, func, arg);
+       if (rcode != 0) {
+               fr_strerror_printf("Failed creating thread: %s", fr_syserror(rcode));
+               pthread_attr_destroy(&attr);
+               return -1;
+       }
+       pthread_attr_destroy(&attr);
+
+       return 0;
+}
+
+/** Wait for multiple threads to signal readiness via a semaphore
+ *
+ * @param[in] sem              semaphore to wait on.
+ * @param[in] count            number of times to wait (once per thread).
+ */
+void fr_thread_wait(fr_sem_t *sem, unsigned int count)
+{
+       unsigned int i;
+
+       for (i = 0; i < count; i++) {
+               SEM_WAIT_INTR(sem);
+       }
+}
+
 /** Common setup for child threads: block signals, allocate a talloc context, and create an event list
  *
  * @param[out] out_ctx The talloc ctx we allocate
@@ -96,6 +144,9 @@ int fr_thread_setup(TALLOC_CTX **out_ctx, fr_event_list_t **out_el, char const *
 int fr_thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el)
 {
 #ifdef WITH_TLS
+       /*
+        *      Modules may use thread-specific OpenSSL contexts, so initialize this first.
+        */
        if (fr_openssl_thread_init(main_config->openssl_async_pool_init,
                                   main_config->openssl_async_pool_max) < 0) return -1;
 #endif
index 30c2fcf12dde77d0e9af80d75c50ac213a84a7be..73a5d4cbdaeffaba141533718610b17cd60fa1d3 100644 (file)
@@ -30,6 +30,14 @@ RCSIDH(thread_h, "$Id$")
 #include <freeradius-devel/util/talloc.h>
 #include <freeradius-devel/util/dlist.h>
 
+#include <pthread.h>
+
+typedef void *(*fr_thread_entry_t)(void *);
+
+int    fr_thread_create(pthread_t *thread, fr_thread_entry_t func, void *arg);
+
+void   fr_thread_wait(fr_sem_t *sem, unsigned int count);
+
 int    fr_thread_setup(TALLOC_CTX **ctx, fr_event_list_t **el, char const *name);
 
 int    fr_thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el);
index 6105147fd89ad1bac18fb7d9d53afc461f9b1a10..75084ffc948cca932265ea6bbfd5a70285389266 100644 (file)
@@ -544,7 +544,7 @@ int sigtran_event_start(void)
         */
        pthread_sigmask(SIG_BLOCK, &sigmask, NULL);
 
-       if (fr_schedule_pthread_create(&event_thread, sigtran_event_loop, NULL) < 0) {
+       if (fr_thread_create(&event_thread, sigtran_event_loop, NULL) < 0) {
                ERROR("main thread - Failed spawning thread for multiplexer event loop: %s", fr_syserror(errno));
                return -1;
        }