]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add an UNLANG_ACTION_YIELD action
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 11 Nov 2017 15:54:26 +0000 (15:54 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 11 Nov 2017 15:54:26 +0000 (15:54 +0000)
It's more explicit than just using the rcode

src/include/interpreter.h
src/main/unlang_interpret.c

index e2081f9967c6346d53ca963f29f1db5b14770f5d..fb3e75c56429cda11a43d17fcd820109370b3db9 100644 (file)
@@ -87,6 +87,7 @@ typedef enum {
        UNLANG_ACTION_PUSHED_CHILD,             //!< #unlang_t pushed a new child onto the stack,
                                                //!< execute it instead of continuing.
        UNLANG_ACTION_BREAK,                    //!< Break out of the current group.
+       UNLANG_ACTION_YIELD,                    //!< Temporarily pause execution until an event occurs.
        UNLANG_ACTION_STOP_PROCESSING           //!< Break out of processing the current request (unwind).
 } unlang_action_t;
 
index fa545833ae22aa67fb20840167a85c91b6e06156..4fcf56b3104c97d90ada41800014e5c9c78e960e 100644 (file)
@@ -35,6 +35,7 @@ static FR_NAME_NUMBER unlang_action_table[] = {
        { "continue",           UNLANG_ACTION_CONTINUE },
        { "pushed-child",       UNLANG_ACTION_PUSHED_CHILD },
        { "break",              UNLANG_ACTION_BREAK },
+       { "yield",              UNLANG_ACTION_YIELD },
        { "stop",               UNLANG_ACTION_STOP_PROCESSING },
        { NULL, -1 }
 };
@@ -803,7 +804,7 @@ static unlang_action_t unlang_detach(REQUEST *request,
        rad_assert(request->backlog != NULL);
 
        *presult = RLM_MODULE_YIELD;
-       return UNLANG_ACTION_CALCULATE_RESULT;
+       return UNLANG_ACTION_YIELD;
 }
 
 static unlang_action_t unlang_call(REQUEST *request,
@@ -985,7 +986,7 @@ static unlang_action_t unlang_subrequest(REQUEST *request,
        }
 
        *presult = RLM_MODULE_YIELD;
-       return UNLANG_ACTION_CALCULATE_RESULT;
+       return UNLANG_ACTION_YIELD;
 }
 
 /** Parallel children have states
@@ -1349,7 +1350,7 @@ static unlang_action_t unlang_parallel(REQUEST *request,
        }
 
        *presult = RLM_MODULE_YIELD;
-       return UNLANG_ACTION_CALCULATE_RESULT;
+       return UNLANG_ACTION_YIELD;
 }
 
 static unlang_action_t unlang_case(REQUEST *request,
@@ -1724,7 +1725,7 @@ static unlang_action_t unlang_map(REQUEST *request,
 
        *presult = map_proc(request, g->proc_inst);
 
-       return UNLANG_ACTION_CALCULATE_RESULT;
+       return *presult == RLM_MODULE_YIELD ? UNLANG_ACTION_YIELD : UNLANG_ACTION_CALCULATE_RESULT;
 }
 
 
@@ -1806,7 +1807,7 @@ done:
        RDEBUG2("%s (%s)", instruction->name ? instruction->name : "",
                fr_int2str(mod_rcode_table, *presult, "<invalid>"));
 
-       return UNLANG_ACTION_CALCULATE_RESULT;
+       return *presult == RLM_MODULE_YIELD ? UNLANG_ACTION_YIELD : UNLANG_ACTION_CALCULATE_RESULT;
 }
 
 
@@ -1932,7 +1933,7 @@ static unlang_action_t unlang_resume(REQUEST *request,
                *priority = instruction->actions[*presult];
        }
 
-       return UNLANG_ACTION_CALCULATE_RESULT;
+       return *presult == RLM_MODULE_YIELD ? UNLANG_ACTION_YIELD : UNLANG_ACTION_CALCULATE_RESULT;
 }
 
 /*
@@ -2239,31 +2240,44 @@ static inline unlang_frame_action_t unlang_frame_eval(REQUEST *request, unlang_s
                        frame->next = NULL;
                        return UNLANG_FRAME_ACTION_POP;
 
-               case UNLANG_ACTION_CALCULATE_RESULT:
-                       if (*result == RLM_MODULE_YIELD) {
-                               /*
-                                *      Detach is magic.  The parent
-                                *      "create" function takes care
-                                *      of bumping the instruction
-                                *      pointer...
-                                */
-                               if (frame->instruction->type == UNLANG_TYPE_DETACH) {
-                                       RDEBUG4("** [%i] %s - detaching child with current (%s %d)",
-                                               stack->depth, __FUNCTION__,
-                                               fr_int2str(mod_rcode_table, frame->result, "<invalid>"),
-                                               frame->priority);
-                                       DUMP_STACK;
-                                       *result = RLM_MODULE_YIELD;
-                               }
+               case UNLANG_ACTION_YIELD:
+               yield:
+                       *result = RLM_MODULE_YIELD;     /* Fixup rcode */
+
+                       /*
+                        *      Detach is magic.  The parent "create" function
+                        *      takes care of bumping the instruction
+                        *      pointer...
+                        */
+                       switch (frame->instruction->type) {
+                       case UNLANG_TYPE_DETACH:
+                               RDEBUG4("** [%i] %s - detaching child with current (%s %d)",
+                                       stack->depth, __FUNCTION__,
+                                       fr_int2str(mod_rcode_table, frame->result, "<invalid>"),
+                                       frame->priority);
+                               DUMP_STACK;
+
+                               return UNLANG_FRAME_ACTION_YIELD;
 
-                               rad_assert(frame->instruction->type == UNLANG_TYPE_RESUME);
+                       case UNLANG_TYPE_RESUME:
                                frame->repeat = true;
                                RDEBUG4("** [%i] %s - yielding with current (%s %d)", stack->depth, __FUNCTION__,
                                        fr_int2str(mod_rcode_table, frame->result, "<invalid>"),
                                        frame->priority);
                                DUMP_STACK;
-                               *result = RLM_MODULE_YIELD;
                                return UNLANG_FRAME_ACTION_YIELD;
+
+                       default:
+                               rad_assert(0);
+                               return UNLANG_FRAME_ACTION_YIELD;
+                       }
+                       break;  /* Static analysis tools are stupid */
+
+               case UNLANG_ACTION_CALCULATE_RESULT:
+                       /* Temporary fixup - ops should return the correct code */
+                       if (frame->result == RLM_MODULE_YIELD) {
+                               action = UNLANG_ACTION_YIELD;
+                               goto yield;
                        }
 
                        frame->repeat = false;