* Work back from the deepest frame
* looking for modules.
*/
- for (depth = unlang_current_depth(request); depth > 0; depth--) {
+ for (depth = stack_depth_current(request); depth > 0; depth--) {
unlang_stack_frame_t *frame = &stack->frame[depth];
/*
#define DUMP_STACK
#endif
-/** Different operations the interpret can execute
- */
-unlang_op_t unlang_ops[UNLANG_TYPE_MAX];
-
-
-static inline void frame_state_init(unlang_stack_t *stack, unlang_stack_frame_t *frame)
-{
- unlang_t const *instruction = frame->instruction;
- unlang_op_t *op;
- char const *name;
-
- op = &unlang_ops[instruction->type];
- name = op->frame_state_name ? op->frame_state_name : __location__;
-
- frame->process = op->interpret;
- frame->signal = op->signal;
-
-#ifdef HAVE_TALLOC_ZERO_POOLED_OBJECT
- /*
- * Pooled object
- */
- if (op->frame_state_pool_size && op->frame_state_size) {
- MEM(frame->state = _talloc_zero_pooled_object(stack,
- op->frame_state_size, name,
- op->frame_state_pool_objects,
- op->frame_state_pool_size));
- } else
-#endif
- /*
- * Pool
- */
- if (op->frame_state_pool_size && !op->frame_state_size) {
- MEM(frame->state = talloc_pool(stack,
- op->frame_state_pool_size +
- ((20 + 68 + 15) * op->frame_state_pool_objects))); /* from samba talloc.c */
- talloc_set_name_const(frame->state, name);
- /*
- * Object
- */
- } else if (op->frame_state_size) {
- MEM(frame->state = _talloc_zero(stack, op->frame_state_size, name));
- }
-}
-
/** Push a new frame onto the stack
*
* @param[in] request to push the frame onto.
return frame->next ? UNLANG_FRAME_ACTION_NEXT : UNLANG_FRAME_ACTION_POP;
}
-/** Cleanup any lingering frame state
- *
- */
-static inline CC_HINT(always_inline) void frame_cleanup(unlang_stack_frame_t *frame)
-{
- /*
- * Don't clear top_frame flag, bad things happen...
- */
- repeatable_clear(frame);
- break_point_clear(frame);
- return_point_clear(frame);
- yielded_clear(frame);
- if (frame->state) {
- talloc_free_children(frame->state); /* *(ev->parent) = NULL in event.c */
- TALLOC_FREE(frame->state);
- }
-}
-
-/** Advance to the next sibling instruction
- *
- */
-static inline CC_HINT(always_inline) void frame_next(unlang_stack_t *stack, unlang_stack_frame_t *frame)
-{
- frame_cleanup(frame);
- frame->instruction = frame->next;
-
- if (!frame->instruction) return;
-
- frame->next = frame->instruction->next;
-
- frame_state_init(stack, frame);
-}
-
-/** Pop a stack frame, removing any associated dynamically allocated state
- *
- * @param[in] stack frame to pop.
- */
-static inline CC_HINT(always_inline) void frame_pop(unlang_stack_t *stack)
-{
- unlang_stack_frame_t *frame;
-
- fr_assert(stack->depth > 1);
-
- frame = &stack->frame[stack->depth];
-
- frame_cleanup(frame);
-
- frame = &stack->frame[--stack->depth];
-
- if (stack->unwind && is_repeatable(frame) && !is_break_point(frame) && !is_return_point(frame)) {
- repeatable_clear(frame);
- }
-}
-
/** Evaluates all the unlang nodes in a section
*
* @param[in] request The current request.
return intp;
}
+/** Discard the bottom most frame on the request's stack
+ *
+ * This is used for cleaning up after errors. i.e. the caller
+ * uses a push function, and experiences an error and needs to
+ * remove the frame that was just pushed.
+ */
+void unlang_interpet_frame_discard(request_t *request)
+{
+ frame_pop(request->stack);
+}
+
/** Set a specific interpreter for a request
*
*/
unlang_interpret_t *unlang_interpret_init(TALLOC_CTX *ctx,
fr_event_list_t *el, unlang_request_func_t *func, void *uctx);
+void unlang_interpet_frame_discard(request_t *request);
+
void unlang_interpret_set(request_t *request, unlang_interpret_t *intp);
unlang_interpret_t *unlang_interpret_get(request_t *request);
unlang_module_t *mc = unlang_generic_to_module(frame->instruction);
char const *caller;
rlm_rcode_t rcode = *p_result;
- int stack_depth = unlang_current_depth(request);
+ int stack_depth = stack_depth_current(request);
unlang_action_t ua;
fr_assert(state->resume != NULL);
}
if (ua == UNLANG_ACTION_YIELD) {
- if (stack_depth < unlang_current_depth(request)) return UNLANG_ACTION_PUSHED_CHILD;
- fr_assert(stack_depth == unlang_current_depth(request));
+ if (stack_depth < stack_depth_current(request)) return UNLANG_ACTION_PUSHED_CHILD;
+ fr_assert(stack_depth == stack_depth_current(request));
*p_result = rcode;
return UNLANG_ACTION_YIELD;
}
{
unlang_module_t *mc;
unlang_frame_state_module_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_module_t);
- int stack_depth = unlang_current_depth(request);
+ int stack_depth = stack_depth_current(request);
char const *caller;
rlm_rcode_t rcode = RLM_MODULE_NOOP;
unlang_action_t ua;
mc = unlang_generic_to_module(frame->instruction);
fr_assert(mc);
- RDEBUG4("[%i] %s - %s (%s)", unlang_current_depth(request), __FUNCTION__,
+ RDEBUG4("[%i] %s - %s (%s)", stack_depth_current(request), __FUNCTION__,
mc->instance->name, mc->instance->module->name);
/*
/*
* Don't allow returning _through_ modules
*/
- return_point_set(unlang_current_frame(request));
+ return_point_set(frame_current(request));
/*
* For logging unresponsive children.
if (ua == UNLANG_ACTION_YIELD) {
state->thread->active_callers++;
- if (stack_depth < unlang_current_depth(request)) return UNLANG_ACTION_PUSHED_CHILD;
- fr_assert(stack_depth == unlang_current_depth(request));
+ if (stack_depth < stack_depth_current(request)) return UNLANG_ACTION_PUSHED_CHILD;
+ fr_assert(stack_depth == stack_depth_current(request));
frame->process = unlang_module_resume;
return UNLANG_ACTION_YIELD;
}
if (action != FR_SIGNAL_DETACH) return;
- frame = unlang_current_frame(request->parent);
+ frame = frame_current(request->parent);
state = talloc_get_type_abort(frame->state, unlang_parallel_state_t);
RDEBUG3("parallel - child %s (%d/%d) DETACHED",
* Reach into the parent to get the unlang_parallel_state_t
* for the whole parallel block.
*/
- unlang_stack_frame_t *frame = unlang_current_frame(request->parent);
+ unlang_stack_frame_t *frame = frame_current(request->parent);
unlang_parallel_state_t *state = talloc_get_type_abort(frame->state, unlang_parallel_state_t);
RDEBUG3("parallel - child %s (%d/%d) EXITED",
state->priority = priority;
RDEBUG4("** [%i] %s - over-riding result from higher priority to (%s %d)",
- unlang_current_depth(request), __FUNCTION__,
+ stack_depth_current(request), __FUNCTION__,
fr_table_str_by_value(mod_rcode_table, result, "<invalid>"),
priority);
}
unlang_parallel_child_signal,
UNLANG_TOP_FRAME,
&state->children[i]) < 0) goto error;
- child_frame = unlang_current_frame(child);
+ child_frame = frame_current(child);
return_point_set(child_frame); /* Don't unwind this frame */
state->children[i].num = i;
/*
* Get the PARENT's stack.
*/
- parent_frame = unlang_current_frame(request->parent);
+ parent_frame = frame_current(request->parent);
parent_state = talloc_get_type_abort(frame->state, unlang_frame_state_subrequest_t);
if (!parent_state->detachable) {
unlang_stack_frame_t frame[UNLANG_STACK_MAX]; //!< The stack...
} unlang_stack_t;
+/** Different operations the interpreter can execute
+ */
+extern unlang_op_t unlang_ops[];
+
+#define MOD_NUM_TYPES (UNLANG_TYPE_XLAT + 1)
+
+extern fr_table_num_sorted_t const mod_rcode_table[];
+extern size_t mod_rcode_table_len;
+
#define UNWIND_FLAG_NONE 0x00 //!< No flags.
#define UNWIND_FLAG_REPEAT 0x01 //!< Repeat the frame on the way up the stack.
#define UNWIND_FLAG_TOP_FRAME 0x02 //!< are we the top frame of the stack?
return UNLANG_ACTION_UNWIND;
}
-static inline unlang_stack_frame_t *unlang_current_frame(request_t *request)
+static inline unlang_stack_frame_t *frame_current(request_t *request)
{
unlang_stack_t *stack = request->stack;
return &stack->frame[stack->depth];
}
-static inline int unlang_current_depth(request_t *request)
+static inline int stack_depth_current(request_t *request)
{
unlang_stack_t *stack = request->stack;
return stack->depth;
}
-/** Different operations the interpreter can execute
+static inline void frame_state_init(unlang_stack_t *stack, unlang_stack_frame_t *frame)
+{
+ unlang_t const *instruction = frame->instruction;
+ unlang_op_t *op;
+ char const *name;
+
+ op = &unlang_ops[instruction->type];
+ name = op->frame_state_name ? op->frame_state_name : __location__;
+
+ frame->process = op->interpret;
+ frame->signal = op->signal;
+
+#ifdef HAVE_TALLOC_ZERO_POOLED_OBJECT
+ /*
+ * Pooled object
+ */
+ if (op->frame_state_pool_size && op->frame_state_size) {
+ MEM(frame->state = _talloc_zero_pooled_object(stack,
+ op->frame_state_size, name,
+ op->frame_state_pool_objects,
+ op->frame_state_pool_size));
+ } else
+#endif
+ /*
+ * Pool
+ */
+ if (op->frame_state_pool_size && !op->frame_state_size) {
+ MEM(frame->state = talloc_pool(stack,
+ op->frame_state_pool_size +
+ ((20 + 68 + 15) * op->frame_state_pool_objects))); /* from samba talloc.c */
+ talloc_set_name_const(frame->state, name);
+ /*
+ * Object
+ */
+ } else if (op->frame_state_size) {
+ MEM(frame->state = _talloc_zero(stack, op->frame_state_size, name));
+ }
+}
+
+/** Cleanup any lingering frame state
+ *
*/
-extern unlang_op_t unlang_ops[];
+static inline void frame_cleanup(unlang_stack_frame_t *frame)
+{
+ /*
+ * Don't clear top_frame flag, bad things happen...
+ */
+ repeatable_clear(frame);
+ break_point_clear(frame);
+ return_point_clear(frame);
+ yielded_clear(frame);
+ if (frame->state) {
+ talloc_free_children(frame->state); /* *(ev->parent) = NULL in event.c */
+ TALLOC_FREE(frame->state);
+ }
+}
-#define MOD_NUM_TYPES (UNLANG_TYPE_XLAT + 1)
+/** Advance to the next sibling instruction
+ *
+ */
+static inline void frame_next(unlang_stack_t *stack, unlang_stack_frame_t *frame)
+{
+ frame_cleanup(frame);
+ frame->instruction = frame->next;
-extern fr_table_num_sorted_t const mod_rcode_table[];
-extern size_t mod_rcode_table_len;
+ if (!frame->instruction) return;
+
+ frame->next = frame->instruction->next;
+
+ frame_state_init(stack, frame);
+}
+
+/** Pop a stack frame, removing any associated dynamically allocated state
+ *
+ * @param[in] stack frame to pop.
+ */
+static inline void frame_pop(unlang_stack_t *stack)
+{
+ unlang_stack_frame_t *frame;
+
+ fr_assert(stack->depth > 1);
+
+ frame = &stack->frame[stack->depth];
+
+ frame_cleanup(frame);
+
+ frame = &stack->frame[--stack->depth];
+
+ if (stack->unwind && is_repeatable(frame) && !is_break_point(frame) && !is_return_point(frame)) {
+ repeatable_clear(frame);
+ }
+}
/** @name Conversion functions for converting #unlang_t to its specialisations
*