* - 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
*
* 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);
#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);
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.
{
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;
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;
* - 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;
} 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
#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.
*
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));
/*
* 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;
}
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();
*/
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.
xlat_unregister(NULL, "poke", xlat_poke);
+ /*
+ * Free the event list.
+ */
+ talloc_free(el);
+
/*
* Detach modules, connection pools, registered xlats / paircompares / maps.
*/
* 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;