]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Pass the event list to the thread instantiate function
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 26 Nov 2016 16:59:25 +0000 (11:59 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 26 Nov 2016 22:17:31 +0000 (17:17 -0500)
src/include/modules.h
src/include/radiusd.h
src/main/modules.c
src/main/threads.c
src/main/unit_test_module.c
src/modules/rlm_rest/rlm_rest.c

index cdee09f8324469666d22bcef3e133d961ccac288..ef413afe5cd064bc57c42b71f3cfb696ab13f40c 100644 (file)
@@ -121,7 +121,7 @@ typedef int (*module_instantiate_t)(CONF_SECTION *mod_cs, void *instance);
  *     - 0 on success.
  *     - -1 if instantiation failed.
  */
-typedef int (*module_thread_t)(void *instance, void *thread);
+typedef int (*module_thread_t)(fr_event_list_t *el, void *instance, void *thread);
 
 /** Module thread destruction callback
  *
@@ -176,7 +176,7 @@ exfile_t *module_exfile_init(TALLOC_CTX *ctx,
  *     Create free and destroy module instances
  */
 void           *module_thread_instance_find(void *inst);
-int            modules_thread_instantiate(CONF_SECTION *root) CC_HINT(nonnull);
+int            modules_thread_instantiate(CONF_SECTION *root, fr_event_list_t *el) CC_HINT(nonnull);
 int            modules_instantiate(CONF_SECTION *root) CC_HINT(nonnull);
 int            modules_bootstrap(CONF_SECTION *root) CC_HINT(nonnull);
 int            modules_free(void);
index 64107d200a9d5882259f0fdb77e550f8fd193746..2b0fd766ae7bc26b7d4e68e8c02505f2ec05f659 100644 (file)
@@ -574,7 +574,6 @@ int radius_copy_vp(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, char con
 #define pair_make_config(_a, _b, _c) fr_pair_make(request, &request->control, _a, _b, _c)
 
 /* threads.c */
-fr_event_list_t        *thread_event_list(void);
 int            thread_pool_bootstrap(CONF_SECTION *cs, bool *spawn_workers);
 int            thread_pool_init(void);
 void           thread_pool_stop(void);
index 6e83edcc0591e8e017cbad78e6b60478f0871f7b..f92cad6bc481a1e6b505df5668d26c0653cc43e1 100644 (file)
@@ -527,10 +527,15 @@ static int _module_thread_inst_tree_cmp(void const *a, void const *b)
        return 0;
 }
 
+typedef struct {
+       rbtree_t        *tree;          //!< Containing the thread instances.
+       fr_event_list_t *el;            //!< Event list for this thread.
+} _thread_intantiate_ctx_t;
+
 /** Setup thread specific instance data for a module
  *
  * @param[in] instance of module to perform thread instantiation for.
- * @param[in] ctx      modules section, containing instance data.
+ * @param[in] ctx      additional arguments to pass to a module's thread_instantiate function.
  * @return
  *     - 0 on success.
  *     - -1 on failure.
@@ -539,7 +544,7 @@ static int _module_thread_instantiate(void *instance, void *ctx)
 {
        module_instance_t               *inst = talloc_get_type_abort(instance, module_instance_t);
        module_thread_instance_t        *thread_inst;
-       rbtree_t                        *thread_inst_tree = talloc_get_type_abort(ctx, rbtree_t);
+       _thread_intantiate_ctx_t        *thread_inst_ctx = ctx;
        int                             ret;
 
        if (!inst->module->thread_instantiate) return 0;
@@ -551,14 +556,20 @@ static int _module_thread_instantiate(void *instance, void *ctx)
                char *type_name;
 
                MEM(thread_inst->data = talloc_zero_array(thread_inst, uint8_t, inst->module->thread_inst_size));
+
+               /*
+                *      Fixup the type name, incase something calls
+                *      talloc_get_type_abort() on it...
+                */
                MEM(type_name = talloc_asprintf(NULL, "%s_thread_t", inst->name));
                talloc_set_name(thread_inst->data, "%s", type_name);
                talloc_free(type_name);
+
                talloc_set_destructor(thread_inst->data, _module_thread_instance_free);
-               rbtree_insert(thread_inst_tree, thread_inst);
+               rbtree_insert(thread_inst_ctx->tree, thread_inst);
        }
 
-       ret = inst->module->thread_instantiate(inst, thread_inst->data);
+       ret = inst->module->thread_instantiate(thread_inst_ctx->el, inst, thread_inst->data);
        if (ret < 0) {
                ERROR("Thread instantiation failed for module \"%s\"", inst->name);
                return -1;
@@ -576,21 +587,25 @@ static int _module_thread_instantiate(void *instance, void *ctx)
  *     - 0 on success.
  *     - -1 on failure.
  */
-int modules_thread_instantiate(CONF_SECTION *root)
+int modules_thread_instantiate(CONF_SECTION *root, fr_event_list_t *el)
 {
-       CONF_SECTION *modules;
-       rbtree_t *thread_inst_tree;
+       CONF_SECTION                    *modules;
+       rbtree_t                        *thread_inst_tree;
+       _thread_intantiate_ctx_t        ctx;
 
        modules = cf_section_sub_find(root, "modules");
        if (!modules) return 0;
 
        thread_inst_tree = fr_thread_local_init(module_thread_inst_tree, _module_thread_inst_tree_free);
        if (!thread_inst_tree) {
-               MEM(thread_inst_tree = rbtree_create(NULL, _module_thread_inst_tree_cmp, rbtree_node_talloc_free, 0));
-               module_thread_inst_tree = thread_inst_tree;
+               MEM(thread_inst_tree = module_thread_inst_tree = rbtree_create(NULL, _module_thread_inst_tree_cmp,
+                                                                              rbtree_node_talloc_free, 0));
        }
 
-       if (cf_data_walk(modules, CF_DATA_TYPE_MODULE_INSTANCE, _module_thread_instantiate, thread_inst_tree) < 0) {
+       ctx.el = el;
+       ctx.tree = thread_inst_tree;
+
+       if (cf_data_walk(modules, CF_DATA_TYPE_MODULE_INSTANCE, _module_thread_instantiate, &ctx) < 0) {
                _module_thread_inst_tree_free(thread_inst_tree);        /* make re-entrant */
                module_thread_inst_tree = NULL;
                return -1;
index 0d8cf06b40e126d57400f729278238773f3cc7eb..4bc02ac5e03335c490152c37058d0bce824af7b5 100644 (file)
@@ -97,16 +97,6 @@ typedef struct fr_pps_t {
 } fr_pps_t;
 #endif
 
-/** Holds this thread's event_list
- *
- * Some modules need direct access to the event_list, so they can
- * insert events that fire independently of processing requests.
- *
- * Libcurl is a good example of this, where it manages its own timers
- * for IO events, and needs to be awoken, when a timeout expires.
- */
-static _Thread_local fr_event_list_t *thread_el;
-
 /*
  *     A data structure to manage the thread pool.  There's no real
  *     need for a data structure, but it makes things conceptually
@@ -446,18 +436,6 @@ static void thread_process_request(THREAD_HANDLE *thread, REQUEST *request)
 #endif
 }
 
-/** Return this thread's event list
- *
- * Can be used by modules to get the event_list for the current thread,
- * so that they can add their own timers outside of request processing.
- *
- * @return This thread's fr_event_list_t.
- */
-fr_event_list_t *thread_event_list(void)
-{
-       return thread_el;
-}
-
 /*
  *     The main thread handler for requests.
  *
@@ -477,7 +455,7 @@ static void *thread_handler(void *arg)
 
        ctx = talloc_init("thread");
 
-       el = thread_el = fr_event_list_create(ctx, NULL, NULL);
+       el = fr_event_list_create(ctx, NULL, NULL);
        rad_assert(el != NULL);
 
        local_backlog = fr_heap_create(timestamp_cmp, offsetof(REQUEST, heap_id));
@@ -496,7 +474,7 @@ static void *thread_handler(void *arg)
        /*
         *      Perform thread specific module instantiation
         */
-       if (modules_thread_instantiate(main_config.config) < 0) {
+       if (modules_thread_instantiate(main_config.config, el) < 0) {
                ERROR("Thread instantiation failed");
                goto done;
        }
index 6f83784b3a2f56cba6aaf51b5100504b03fcc8e3..bf121abbf885e48219d3b43623ae91c379e4ba87 100644 (file)
@@ -655,6 +655,7 @@ int main(int argc, char *argv[])
        VALUE_PAIR              *filter_vps = NULL;
        bool                    xlat_only = false;
        fr_state_tree_t         *state = NULL;
+       fr_event_list_t         *el = NULL;
 
        fr_talloc_fault_setup();
 
@@ -816,10 +817,16 @@ int main(int argc, char *argv[])
         */
        if (modules_instantiate(main_config.config) < 0) goto exit_failure;
 
+       /*
+        *      Create a dummy event list
+        */
+       el = fr_event_list_create(NULL, NULL, NULL);
+       rad_assert(el != NULL);
+
        /*
         *      Perform any thread specific instantiation
         */
-       if (modules_thread_instantiate(main_config.config) < 0) goto exit_failure;
+       if (modules_thread_instantiate(main_config.config, el) < 0) goto exit_failure;
 
        /*
         *      And then load the virtual servers.
@@ -961,6 +968,11 @@ finish:
 
        xlat_unregister(NULL, "poke", xlat_poke);
 
+       /*
+        *      Free the event list.
+        */
+       talloc_free(el);
+
        /*
         *      Detach modules, connection pools, registered xlats / paircompares / maps.
         */
index 0382d3489bc66f41d015360838b34f3cfecbd5ec..a4338a5829c46661d8ff0f5064950640bb5683af 100644 (file)
@@ -785,13 +785,16 @@ static int parse_sub_section(CONF_SECTION *parent, CONF_PARSER const *config_ite
  * Easy handles representing requests are added to the curl multihandle
  * with the multihandle used for mux/demux.
  *
+ * @param[in] cs       Module config.
  * @param[in] instance of rlm_rest_t.
  * @param[in] thread   specific data.
+ * @param[in] el       associated with this thread.
  * @return
  *     - 0 on success.
  *     - -1 on failure.
  */
-static int mod_thread_instantiate(UNUSED void *instance, void *thread)
+static int mod_thread_instantiate(UNUSED CONF_SECTION const *cs, UNUSED void *instance, UNUSED fr_event_list_t *el,
+                                 void *thread)
 {
        rlm_rest_thread_t       *t = thread;