This mostly saves on boilerplate at the top of every module call.
module_method_t method; //!< Module method to call
call_env_method_t const *method_env; //!< Method specific call_env.
+ size_t rctx_size; //!< If set, this overrides the module_t rctx_size.
+ ///< Instructs the module instruction to pre-allocate
+ ///< an rctx (available in mctx->rctx) before the module
+ ///< method is called.
+ char const *rctx_type; //!< If rctx_size is used from the mmb, this sets the
+ ///< type of the rctx.
+
fr_dlist_head_t same_name1; //!< List of bindings with the same name1. Only initialised
///< for the the first name1 binding.
///< DO NOT INITIALISE IN THE MODULE.
size_t thread_inst_size; //!< Size of the module's thread-specific instance data.
char const *thread_inst_type; //!< talloc type to assign to thread instance data.
+
+ size_t rctx_size; //!< Size of the module's thread-specific data.
+ char const *rctx_type; //!< talloc type to assign to thread instance data.
};
+#define TALLOCED_TYPE(_field, _ctype) \
+ ._field##_size = sizeof(_ctype), ._field##_type = #_ctype
+
+#define MODULE_BOOT(_ctype) TALLOCED_TYPE(boot, _ctype)
+#define MODULE_INST(_ctype) TALLOCED_TYPE(inst, _ctype)
+#define MODULE_THREAD_INST(_ctype) TALLOCED_TYPE(thread_inst, _ctype)
+#define MODULE_RCTX(_ctype) TALLOCED_TYPE(rctx, _ctype)
+
/** What state the module instance is currently in
*
*/
*/
if (fr_time_delta_ispos(frame->instruction->actions.retry.irt)) now = fr_time();
+ /*
+ * Pre-allocate an rctx for the module, if it has one.
+ */
+ fr_assert_msg(state->rctx == NULL, "rctx should be NULL for initial module call");
+ {
+ size_t size = 0;
+ char const *type;
+
+ /*
+ * Use the module method binding's rctx size in preference
+ * to the one set for the module as a whole.
+ */
+ if (m->mmc.mmb.rctx_size) {
+ size = m->mmc.mmb.rctx_size;
+ type = m->mmc.mmb.rctx_type;
+ /*
+ * Use the rctx from the module_t
+ *
+ * The module is still fine to allocate the rctx itself
+ * in the first module method call.
+ */
+ } else if(m->mmc.mi->exported->rctx_size) {
+ size = m->mmc.mi->exported->rctx_size;
+ type = m->mmc.mi->exported->rctx_type;
+ }
+
+ if (size > 0) {
+ MEM(state->rctx = talloc_zero_array(state, uint8_t, size));
+ if (!type) {
+ talloc_set_name(state->rctx, "%s_rctx_t", m->mmc.mi->name);
+ } else {
+ talloc_set_name_const(state->rctx, type);
+ }
+ }
+ }
+
request->module = m->mmc.mi->name;
safe_lock(m->mmc.mi); /* Noop unless instance->mutex set */
ua = m->mmc.mmb.method(&state->rcode,
- MODULE_CTX(m->mmc.mi, state->thread->data, state->env_data, NULL),
+ MODULE_CTX(m->mmc.mi, state->thread->data, state->env_data, state->rctx),
request);
safe_unlock(m->mmc.mi);
.magic = MODULE_MAGIC_INIT,
.name = "ldap",
.flags = 0,
- .boot_size = sizeof(rlm_ldap_boot_t),
- .boot_type = "rlm_ldap_boot_t",
- .inst_size = sizeof(rlm_ldap_t),
+ MODULE_BOOT(rlm_ldap_boot_t),
+ MODULE_INST(rlm_ldap_t),
.config = module_config,
.onload = mod_load,
.unload = mod_unload,
.bootstrap = mod_bootstrap,
.instantiate = mod_instantiate,
.detach = mod_detach,
- .thread_inst_size = sizeof(fr_ldap_thread_t),
- .thread_inst_type = "fr_ldap_thread_t",
+ MODULE_THREAD_INST(fr_ldap_thread_t),
.thread_instantiate = mod_thread_instantiate,
.thread_detach = mod_thread_detach,
},