RDEBUG2("repeat %s", is_repeatable(frame) ? "yes" : "no");
RDEBUG2("break_point %s", is_break_point(frame) ? "yes" : "no");
RDEBUG2("return_point %s", is_return_point(frame) ? "yes" : "no");
- RDEBUG2("resumable %s", is_resumable(frame) ? "yes" : "no");
+ RDEBUG2("resumable %s", is_yielded(frame) ? "yes" : "no");
REXDENT();
}
repeatable_clear(frame);
break_point_clear(frame);
return_point_clear(frame);
- resumable_clear(frame);
+ yielded_clear(frame);
if (frame->state) TALLOC_FREE(frame->state);
}
REQUEST_VERIFY(request);
/*
- * We may be multiple layers deep in create{} or
- * parallel{}. Only the top-level request is
- * tracked && marked "stop processing".
+ * We're running this frame, so it can't possibly be yielded.
*/
- parent = request;
- while (parent->parent) parent = parent->parent;
+ yielded_clear(frame);
/*
- * We've been asked to stop. Do so.
+ * Child requests are scheduled, so they may be
+ * marked as "stop". Or one of the parents may
+ * be marked as "stop".
*/
- if (parent->master_state == REQUEST_STOP_PROCESSING) {
- do_stop:
- frame->result = RLM_MODULE_FAIL;
- frame->priority = 9999;
- unwind_all(stack);
- break;
+ for (parent = request;
+ parent != NULL;
+ parent = parent->parent) {
+ if (parent->master_state == REQUEST_STOP_PROCESSING) {
+ do_stop:
+ frame->result = RLM_MODULE_FAIL;
+ frame->priority = 9999;
+
+ RDEBUG4("** [%i] %s - STOP current subsection with (%s %d)",
+ stack->depth, __FUNCTION__,
+ fr_table_str_by_value(mod_rcode_table, frame->result, "<invalid>"),
+ frame->priority);
+
+ unwind_all(stack);
+ return UNLANG_FRAME_ACTION_POP;
+ }
}
if (!is_repeatable(frame) && (unlang_ops[instruction->type].debug_braces)) {
case UNLANG_TYPE_PARALLEL: /* until we get rid of UNLANG_TYPE_RESUME */
case UNLANG_TYPE_RESUME:
repeatable_set(frame);
- resumable_set(frame);
+ yielded_set(frame);
RDEBUG4("** [%i] %s - yielding with current (%s %d)", stack->depth, __FUNCTION__,
fr_table_str_by_value(mod_rcode_table, frame->result, "<invalid>"),
frame->priority);
DUMP_STACK;
#endif
- rad_assert(request->runnable_id < 0);
+ rad_assert(!is_scheduled(request)); /* if we're running it, it can't be scheduled */
RDEBUG4("** [%i] %s - interpreter entered", stack->depth, __FUNCTION__);
/*
* Be gracious in errors.
*/
- if (!is_resumable(frame)) continue;
+ if (!is_yielded(frame)) continue;
switch (frame->instruction->type) {
case UNLANG_TYPE_MODULE: /* until we get rid of UNLANG_TYPE_RESUME */
unlang_stack_frame_t *frame = &stack->frame[stack->depth];
/*
- * The request hasn't yield, OR it's already been marked
- * as runnable. Don't do anything.
+ * The request hasn't yielded, OR it's already been
+ * marked as runnable. Don't do anything.
*
* The IO code, or children have no idea where they're
* being called from. They just ask to mark the parent
* Multiple child request may also mark a parent request
* runnable, before the parent request starts running.
*/
- if (!is_resumable(frame) || (request->runnable_id >= 0)) return;
+ if (!is_yielded(frame) || is_scheduled(request)) return;
/*
*/
#define UNWIND_FLAG_BREAK_POINT 0x04 //!< 'break' stops here.
#define UNWIND_FLAG_RETURN_POINT 0x08 //!< 'return' stops here.
#define UNWIND_FLAG_NO_CLEAR 0x10 //!< Keep unwinding, don't clear the unwind flag.
-#define UNWIND_FLAG_RESUMABLE 0x20 //!< Resume point, temporary until we get rid of UNLANG_TYPE_RESUME
+#define UNWIND_FLAG_YIELDED 0x20 //!< frame has yielded
static inline void repeatable_set(unlang_stack_frame_t *frame) { frame->uflags |= UNWIND_FLAG_REPEAT; }
static inline void top_frame_set(unlang_stack_frame_t *frame) { frame->uflags |= UNWIND_FLAG_TOP_FRAME; }
static inline void break_point_set(unlang_stack_frame_t *frame) { frame->uflags |= UNWIND_FLAG_BREAK_POINT; }
static inline void return_point_set(unlang_stack_frame_t *frame) { frame->uflags |= UNWIND_FLAG_RETURN_POINT; }
-static inline void resumable_set(unlang_stack_frame_t *frame) { frame->uflags |= UNWIND_FLAG_RESUMABLE; }
+static inline void yielded_set(unlang_stack_frame_t *frame) { frame->uflags |= UNWIND_FLAG_YIELDED; }
static inline void repeatable_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_REPEAT; }
static inline void top_frame_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_TOP_FRAME; }
static inline void break_point_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_BREAK_POINT; }
static inline void return_point_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_RETURN_POINT; }
-static inline void resumable_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_RESUMABLE; }
+static inline void yielded_clear(unlang_stack_frame_t *frame) { frame->uflags &= ~UNWIND_FLAG_YIELDED; }
static inline bool is_repeatable(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_REPEAT; }
static inline bool is_top_frame(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_TOP_FRAME; }
static inline bool is_break_point(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_BREAK_POINT; }
static inline bool is_return_point(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_RETURN_POINT; }
-static inline bool is_resumable(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_RESUMABLE; }
+static inline bool is_yielded(unlang_stack_frame_t *frame) { return frame->uflags & UNWIND_FLAG_YIELDED; }
+
+static inline bool is_scheduled(REQUEST const *request) { return (request->runnable_id >= 0); }
static inline unlang_action_t unwind_to_break(unlang_stack_t *stack)
{