Skip to content
Permalink
Browse files

rename to yielded_set, etc.

and fix a couple of bugs where yielded wasn't cleared when
instructions were being run.  And where the current request
wasn't being checked for STOP_PROCESSING
  • Loading branch information
alandekok committed Sep 28, 2019
1 parent aa3c953 commit 3bafd0d0c811b2ee88a2ab1aa376035e77d40cee
Showing with 35 additions and 24 deletions.
  1. +29 −20 src/lib/unlang/interpret.c
  2. +6 −4 src/lib/unlang/unlang_priv.h
@@ -77,7 +77,7 @@ static void frame_dump(REQUEST *request, unlang_stack_frame_t *frame)
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();
}

@@ -439,7 +439,7 @@ static inline void frame_cleanup(unlang_stack_frame_t *frame)
repeatable_clear(frame);
break_point_clear(frame);
return_point_clear(frame);
resumable_clear(frame);
yielded_clear(frame);
if (frame->state) TALLOC_FREE(frame->state);
}

@@ -522,22 +522,31 @@ static inline unlang_frame_action_t frame_eval(REQUEST *request, unlang_stack_fr
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)) {
@@ -616,7 +625,7 @@ static inline unlang_frame_action_t frame_eval(REQUEST *request, unlang_stack_fr
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);
@@ -704,7 +713,7 @@ rlm_rcode_t unlang_interpret_run(REQUEST *request)
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__);

@@ -1133,7 +1142,7 @@ static void frame_signal(REQUEST *request, fr_state_signal_t action, int limit)
/*
* 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 */
@@ -1219,8 +1228,8 @@ void unlang_interpret_resumable(REQUEST *request)
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
@@ -1236,7 +1245,7 @@ void unlang_interpret_resumable(REQUEST *request)
* 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;

/*
*/
@@ -293,25 +293,27 @@ typedef struct {
#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)
{

0 comments on commit 3bafd0d

Please sign in to comment.
You can’t perform that action at this time.