*/
typedef struct {
module_thread_instance_t *thread; //!< thread-local data for this module
-} unlang_stack_entry_modcall_t;
+} unlang_stack_state_modcall_t;
/** State of a foreach loop
*
#ifndef NDEBUG
int indent; //!< for catching indentation issues
#endif
-} unlang_stack_entry_foreach_t;
+} unlang_stack_state_foreach_t;
/** State of a redundant operation
*
typedef struct {
unlang_t *child;
unlang_t *found;
-} unlang_stack_entry_redundant_t;
+} unlang_stack_state_redundant_t;
typedef union {
- unlang_stack_entry_modcall_t modcall; //!< State for a modcall.
- unlang_stack_entry_foreach_t foreach; //!< Foreach iterator state.
- unlang_stack_entry_redundant_t redundant; //!< Redundant section state.
-} unlang_stack_entry_t;
+ unlang_stack_state_modcall_t modcall; //!< State for a modcall.
+ unlang_stack_state_foreach_t foreach; //!< Foreach iterator state.
+ unlang_stack_state_redundant_t redundant; //!< Redundant section state.
+} unlang_stack_state_t;
/** Our interpreter stack, as distinct from the C stack
*
*/
typedef struct {
unlang_t *instruction; //!< The unlang node we're evaluating.
- rlm_rcode_t result;
- int priority;
- unlang_type_t unwind; //!< Unwind to this one if it exists.
- bool do_next_sibling : 1;
- bool was_if : 1;
- bool if_taken : 1;
- bool resume : 1;
- bool top_frame : 1;
/** Stack frame specialisations
*
* Which stack_entry specialisation to use is determined by the
* instruction->type.
*/
+ void *state;
+
+ rlm_rcode_t result;
+ int priority;
+ unlang_type_t unwind; //!< Unwind to this one if it exists.
+ //!< This is used for break and return.
+
+ bool do_next_sibling : 1;
+ bool was_if : 1;
+ bool if_taken : 1;
+ bool resume : 1;
+ bool top_frame : 1;
+
union {
- unlang_stack_entry_modcall_t modcall; //!< State for a modcall.
- unlang_stack_entry_foreach_t foreach; //!< Foreach iterator state.
- unlang_stack_entry_redundant_t redundant; //!< Redundant section state.
+ unlang_stack_state_foreach_t foreach; //!< Foreach iterator state.
+ unlang_stack_state_redundant_t redundant; //!< Redundant section state.
};
} unlang_stack_frame_t;
next->was_if = false;
next->if_taken = false;
next->resume = false;
+ next->state = NULL;
}
static inline void unlang_pop(unlang_stack_t *stack)
unlang_module_call_t *sp;
unlang_stack_frame_t *frame = &stack->frame[stack->depth];
unlang_t *instruction = frame->instruction;
+ unlang_stack_state_modcall_t *modcall_state;
/*
* Process a stand-alone child, and fall through
*/
if (request->master_state == REQUEST_STOP_PROCESSING) return UNLANG_ACTION_STOP_PROCESSING;
- RDEBUG4("[%i] %s - %s (%s)", stack->depth, __FUNCTION__, sp->module_instance->name, sp->module_instance->module->name);
+ RDEBUG4("[%i] %s - %s (%s)", stack->depth, __FUNCTION__,
+ sp->module_instance->name, sp->module_instance->module->name);
+ /*
+ * Return administratively configured return code
+ */
if (sp->module_instance->force) {
request->rcode = sp->module_instance->code;
goto done;
}
+ frame->state = modcall_state = talloc_zero(stack, unlang_stack_state_modcall_t);
+
/*
* Grab the thread/module specific data if any exists.
*/
- frame->modcall.thread = module_thread_instance_find(sp->module_instance);
- rad_assert(frame->modcall.thread != NULL);
+ modcall_state->thread = module_thread_instance_find(sp->module_instance);
+ rad_assert(modcall_state->thread != NULL);
/*
* For logging unresponsive children.
*/
request->module = sp->module_instance->name;
- frame->modcall.thread->total_calls++;
+ modcall_state->thread->total_calls++;
/*
* Lock is noop unless instance->mutex is set.
*/
safe_lock(sp->module_instance);
- request->rcode = sp->method(sp->module_instance->data, frame->modcall.thread->data, request);
+ request->rcode = sp->method(sp->module_instance->data, modcall_state->thread->data, request);
safe_unlock(sp->module_instance);
request->module = NULL;
}
if (*presult == RLM_MODULE_YIELD) {
- frame->modcall.thread->active_callers++;
+ modcall_state->thread->active_callers++;
} else {
*priority = instruction->actions[*presult];
}
unlang_t *instruction = frame->instruction;
unlang_module_resumption_t *mr = unlang_generic_to_module_resumption(instruction);
unlang_module_call_t *sp;
+ unlang_stack_state_modcall_t *modcall_state = talloc_get_type_abort(frame->state,
+ unlang_stack_state_modcall_t);
void *mutable;
sp = &mr->module;
}
if (*presult != RLM_MODULE_YIELD) {
- frame->modcall.thread->active_callers--;
+ modcall_state->thread->active_callers--;
*priority = instruction->actions[*presult];
}
unlang_stack_frame_t *frame = &stack->frame[stack->depth];
unlang_event_t *ev;
unlang_module_call_t *sp;
+ unlang_stack_state_modcall_t *modcall_state = talloc_get_type_abort(frame->state,
+ unlang_stack_state_modcall_t);
rad_assert(stack->depth > 0);
rad_assert((frame->instruction->type == UNLANG_TYPE_MODULE_CALL) ||
ev->fd = -1;
ev->timeout = callback;
ev->inst = sp->module_instance->data;
- ev->thread = frame->modcall.thread;
+ ev->thread = modcall_state->thread;
ev->ctx = ctx;
if (fr_event_timer_insert(request->el, unlang_event_timeout_handler, ev, when, &(ev->ev)) < 0) {
unlang_stack_frame_t *frame = &stack->frame[stack->depth];
unlang_event_t *ev;
unlang_module_call_t *sp;
+ unlang_stack_state_modcall_t *modcall_state = talloc_get_type_abort(frame->state,
+ unlang_stack_state_modcall_t);
rad_assert(stack->depth > 0);
ev->fd_write = write;
ev->fd_error = error;
ev->inst = sp->module_instance->data;
- ev->thread = frame->modcall.thread;
+ ev->thread = modcall_state->thread;
ev->ctx = ctx;
/*
unlang_stack_frame_t *frame = &stack->frame[stack->depth];
unlang_module_resumption_t *mr;
unlang_module_call_t *sp;
+ unlang_stack_state_modcall_t *modcall_state = talloc_get_type_abort(frame->state,
+ unlang_stack_state_modcall_t);
rad_assert(stack->depth > 0);
rad_assert(mr != NULL);
memcpy(&mr->module, frame->instruction, sizeof(mr->module));
- mr->thread = frame->modcall.thread;
+ mr->thread = modcall_state->thread;
mr->module.self.type = UNLANG_TYPE_MODULE_RESUME;
mr->callback = callback;
mr->signal_callback = signal_callback;