From: Arran Cudbard-Bell Date: Sat, 26 Nov 2016 16:59:25 +0000 (-0500) Subject: Pass the event list to the thread instantiate function X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3819f633eaca95b2f869e09a0628c696dc3dd29;p=thirdparty%2Ffreeradius-server.git Pass the event list to the thread instantiate function --- diff --git a/src/include/modules.h b/src/include/modules.h index cdee09f8324..ef413afe5cd 100644 --- a/src/include/modules.h +++ b/src/include/modules.h @@ -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); diff --git a/src/include/radiusd.h b/src/include/radiusd.h index 64107d200a9..2b0fd766ae7 100644 --- a/src/include/radiusd.h +++ b/src/include/radiusd.h @@ -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); diff --git a/src/main/modules.c b/src/main/modules.c index 6e83edcc059..f92cad6bc48 100644 --- a/src/main/modules.c +++ b/src/main/modules.c @@ -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; diff --git a/src/main/threads.c b/src/main/threads.c index 0d8cf06b40e..4bc02ac5e03 100644 --- a/src/main/threads.c +++ b/src/main/threads.c @@ -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; } diff --git a/src/main/unit_test_module.c b/src/main/unit_test_module.c index 6f83784b3a2..bf121abbf88 100644 --- a/src/main/unit_test_module.c +++ b/src/main/unit_test_module.c @@ -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. */ diff --git a/src/modules/rlm_rest/rlm_rest.c b/src/modules/rlm_rest/rlm_rest.c index 0382d3489bc..a4338a5829c 100644 --- a/src/modules/rlm_rest/rlm_rest.c +++ b/src/modules/rlm_rest/rlm_rest.c @@ -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;