*/
typedef struct {
unlang_module_call_t module; //!< Module call that returned #RLM_MODULE_YIELD.
+ void *thread; //!< data specific to the module.
fr_unlang_resume_t callback; //!< Function the yielding module indicated should
//!< be called when the request could be resumed.
fr_unlang_action_t action_callback; //!< Function the yielding module indicated should
char *xlat_name;
} unlang_xlat_inline_t;
+typedef struct {
+ void *thread; //!< Thread specific module instance.
+} unlang_stack_entry_modcall_t;
+
/** State of a foreach loop
*
*/
unlang_t *instruction;
union {
+ unlang_stack_entry_modcall_t modcall;
unlang_stack_entry_foreach_t foreach;
unlang_stack_entry_redundant_t redundant;
};
* on a registered FD occurs before the timeout event fires.
*
* @param[in] request the request.
- * @param[in] module_instance the module instance.
+ * @param[in] instance the module instance.
+ * @param[in] thread data specific to this module instance.
* @param[in] ctx a local context for the callback.
* @param[in] fired the time the timeout event actually fired.
*/
-typedef void (*fr_unlang_timeout_callback_t)(REQUEST *request, void *module_instance, void *ctx, struct timeval *fired);
+typedef void (*fr_unlang_timeout_callback_t)(REQUEST *request, void *instance, void *thread, void *ctx,
+ struct timeval *fired);
/** A callback when the FD is ready for reading
*
* @note The callback is automatically removed on unlang_resumable(), so
*
* @param[in] request the current request.
- * @param[in] module_instance the module instance.
+ * @param[in] instance the module instance.
+ * @param[in] thread data specific to this module instance.
* @param[in] ctx a local context for the callback.
* @param[in] fd the file descriptor.
*/
-typedef void (*fr_unlang_fd_callback_t)(REQUEST *request, void *module_instance, void *ctx, int fd);
+typedef void (*fr_unlang_fd_callback_t)(REQUEST *request, void *instance, void *thread, void *ctx, int fd);
/** A callback for when the request is resumed.
*
* The resumed request cannot call the normal "authorize", etc. method. It needs a separate callback.
*
* @param[in] request the current request.
- * @param[in] module_instance The module instance.
+ * @param[in] instance The module instance.
+ * @param[in] thread data specific to this module instance.
* @param[in] ctx a local context for the callback.
* @return a normal rlm_rcode_t.
*/
-typedef rlm_rcode_t (*fr_unlang_resume_t)(REQUEST *request, void *module_instance, void *ctx);
+typedef rlm_rcode_t (*fr_unlang_resume_t)(REQUEST *request, void *instance, void *thread, void *ctx);
/** A callback when the request gets a fr_state_action_t.
*
*
* @note The callback is automatically removed on unlang_resumable().
*
- * param[in] request The current request.
- * param[in] module_instance The module instance.
- * param[in] ctx for the callback.
- * param[in] action which is signalling the request.
+ * @param[in] request The current request.
+ * @param[in] instance The module instance.
+ * @param[in] thread data specific to this module instance.
+ * @param[in] ctx for the callback.
+ * @param[in] action which is signalling the request.
*/
-typedef void (*fr_unlang_action_t)(REQUEST *request, void *module_instance, void *ctx, fr_state_action_t action);
+typedef void (*fr_unlang_action_t)(REQUEST *request, void *instance, void *thread, void *ctx,
+ fr_state_action_t action);
int unlang_event_timeout_add(REQUEST *request, fr_unlang_timeout_callback_t callback,
void const *ctx, struct timeval *timeout);
unlang_module_call_t *sp;
unlang_stack_frame_t *frame = &stack->frame[stack->depth];
unlang_t *instruction = frame->instruction;
- module_thread_instance_t *thread_inst;
/*
* Process a stand-alone child, and fall through
/*
* Grab the thread/module specific data if any exists.
*/
- thread_inst = module_thread_instance_find(sp->module_instance);
+ frame->modcall.thread = module_thread_instance_find(sp->module_instance);
/*
* For logging unresponsive children.
request->module = sp->module_instance->name;
safe_lock(sp->module_instance);
- request->rcode = sp->method(sp->module_instance->data, thread_inst, request);
+ request->rcode = sp->method(sp->module_instance->data, frame->modcall.thread, request);
safe_unlock(sp->module_instance);
request->module = NULL;
memcpy(&mutable, &mr->ctx, sizeof(mutable));
safe_lock(sp->module_instance);
- *presult = mr->callback(request, mr->module.module_instance->data, mutable);
+ *presult = mr->callback(request, mr->module.module_instance->data, mr->thread, mutable);
safe_unlock(sp->module_instance);
RDEBUG2("%s (%s)", instruction->name ? instruction->name : "",
fr_unlang_timeout_callback_t timeout_callback; //!< Function to call on timeout.
fr_unlang_fd_callback_t fd_callback; //!< Function to call when FD is readable.
void const *inst; //!< Module instance to pass to callbacks.
+ void *thread; //!< Thread specific module instance.
void const *ctx; //!< ctx data to pass to callbacks.
fr_event_timer_t *ev; //!< Event in this worker's event heap.
} unlang_event_t;
memcpy(&mutable_ctx, &ev->ctx, sizeof(mutable_ctx));
memcpy(&mutable_inst, &ev->inst, sizeof(mutable_inst));
- ev->timeout_callback(ev->request, mutable_inst, mutable_ctx, now);
+ ev->timeout_callback(ev->request, mutable_inst, ev->thread, mutable_ctx, now);
talloc_free(ev);
}
memcpy(&mutable_ctx, &ev->ctx, sizeof(mutable_ctx));
memcpy(&mutable_inst, &ev->inst, sizeof(mutable_inst));
- ev->fd_callback(ev->request, mutable_inst, mutable_ctx, fd);
+ ev->fd_callback(ev->request, mutable_inst, ev->thread, mutable_ctx, fd);
}
/** Set a timeout for the request.
ev->fd = -1;
ev->timeout_callback = callback;
ev->inst = sp->module_instance->data;
+ ev->thread = frame->modcall.thread;
ev->ctx = ctx;
if (fr_event_timer_insert(request->el, unlang_event_timeout_handler, ev, when, &(ev->ev)) < 0) {
ev->fd = fd;
ev->fd_callback = callback;
ev->inst = sp->module_instance->data;
+ ev->thread = frame->modcall.thread;
ev->ctx = ctx;
if (!fr_event_fd_insert(request->el, fd, unlang_event_fd_handler, NULL, NULL, ev)) {
memcpy(&mutable, &mr->ctx, sizeof(mutable));
- mr->action_callback(request, mr->module.module_instance->data, mutable, action);
+ mr->action_callback(request, mr->module.module_instance->data, mr->thread, mutable, action);
}
/** Yield a request
rad_assert(mr != NULL);
memcpy(&mr->module, frame->instruction, sizeof(mr->module));
-
+ mr->thread = frame->modcall.thread;
mr->module.self.type = UNLANG_TYPE_RESUME;
mr->callback = callback;
mr->action_callback = action_callback;
+ mr->thread = module_thread_instance_find(mr->module.module_instance->data); /* Could have caller pass this? */
mr->ctx = ctx;
frame->instruction = unlang_resumption_to_generic(mr);
/** Called when the delay is complete, and we're running from the interpreter
*
*/
-static rlm_rcode_t delay_return(UNUSED REQUEST *request, UNUSED void *instance, UNUSED void *ctx)
+static rlm_rcode_t delay_return(UNUSED REQUEST *request, UNUSED void *instance, UNUSED void *thread, UNUSED void *ctx)
{
return RLM_MODULE_OK;
}
* @param[in] ctx Scheduled end of the delay.
* @param[in] fired When request processing was resumed.
*/
-static void delay_done(REQUEST *request, UNUSED void *instance, void *ctx, struct timeval *fired)
+static void delay_done(REQUEST *request, UNUSED void *instance, UNUSED void *thread, void *ctx, struct timeval *fired)
{
struct timeval *when = talloc_get_type_abort(ctx, struct timeval);
unlang_resumable(ccr->request);
}
-static void mod_proxy_no_reply(REQUEST *request, UNUSED void *instance, void *ctx, UNUSED struct timeval *now)
+static void mod_proxy_no_reply(REQUEST *request, UNUSED void *instance, UNUSED void *thread, void *ctx,
+ UNUSED struct timeval *now)
{
rlm_radius_client_request_t *ccr = ctx;
}
-static rlm_rcode_t mod_resume_recv(REQUEST *request, void *instance, void *ctx)
+static rlm_rcode_t mod_resume_recv(REQUEST *request, void *instance, UNUSED void *thread, void *ctx)
{
rlm_rcode_t rcode;
rlm_radius_client_instance_t *inst = instance;
return rcode;
}
-static rlm_rcode_t mod_resume_continue(REQUEST *request, void *instance, void *ctx)
+static rlm_rcode_t mod_resume_continue(REQUEST *request, void *instance, void *thread, void *ctx)
{
rlm_rcode_t rcode;
CONF_SECTION *unlang;
child->request_state = REQUEST_RECV;
- return mod_resume_recv(request, instance, ccr);
+ return mod_resume_recv(request, instance, thread, ccr);
}
-static void mod_action_dup(REQUEST *request, void *instance, void *ctx, fr_state_action_t action)
+static void mod_action_dup(REQUEST *request, void *instance, UNUSED void *thread, void *ctx, fr_state_action_t action)
{
rlm_radius_client_instance_t const *inst = instance;
rlm_radius_client_request_t *ccr = ctx;
return unlang_yield(request, mod_resume_continue, mod_action_dup, ccr);
}
-static rlm_rcode_t mod_resume_send(REQUEST *request, void *instance, void *ctx)
+static rlm_rcode_t mod_resume_send(REQUEST *request, void *instance, UNUSED void *thread, void *ctx)
{
rlm_rcode_t rcode;
rlm_radius_client_instance_t const *inst = instance;
/** Send packets outbound.
*
*/
-static rlm_rcode_t CC_HINT(nonnull) mod_process(void *instance, UNUSED void *thread, REQUEST *request)
+static rlm_rcode_t CC_HINT(nonnull) mod_process(void *instance, void *thread, REQUEST *request)
{
rlm_radius_client_instance_t const *inst = instance;
rlm_radius_client_conn_t *conn;
child->request_state = REQUEST_SEND;
- return mod_resume_send(request, instance, ccr);
+ return mod_resume_send(request, instance, thread, ccr);
}
static char const *auth_names[][2] = {