Skip to content

Commit

Permalink
Pass received signals on to xlat functions
Browse files Browse the repository at this point in the history
fff
  • Loading branch information
arr2036 committed Apr 5, 2019
1 parent 571165d commit a110751
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 4 deletions.
14 changes: 14 additions & 0 deletions src/lib/server/xlat_eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,20 @@ static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_cursor_t *out, REQU
static const char xlat_spaces[] = " ";
#endif

/** Signal an xlat function
*
* @param[in] signal function to call.
* @param[in] exp Xlat node that previously yielded.
* @param[in] request The current request.
* @param[in] rctx Opaque (to us), resume ctx provided by the xlat function
* when it yielded.
*/
void xlat_signal(xlat_func_signal_t signal, xlat_exp_t const *exp,
REQUEST *request, void *rctx, fr_state_signal_t action)
{
signal(request, exp->inst, xlat_thread_instance_find(exp)->data, rctx, action);
}

/** Call an xlat's resumption method
*
* @param[in] ctx to allocate value boxes in.
Expand Down
3 changes: 3 additions & 0 deletions src/lib/server/xlat_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ xlat_t *xlat_func_find(char const *name);
/*
* xlat_eval.c
*/
void xlat_signal(xlat_func_signal_t signal, xlat_exp_t const *exp,
REQUEST *request, void *rctx, fr_state_signal_t action);

xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_cursor_t *out,
xlat_func_resume_t resume, xlat_exp_t const *exp,
REQUEST *request, fr_value_box_t **result, void *rctx);
Expand Down
34 changes: 30 additions & 4 deletions src/lib/unlang/xlat.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,31 @@ xlat_action_t unlang_xlat_yield(REQUEST *request,
}
}

/** Send a signal (usually stop) to a request that's running an xlat expansions
*
* This is typically called via an "async" action, i.e. an action
* outside of the normal processing of the request.
*
* If there is no #xlat_func_signal_t callback defined, the action is ignored.
*
* @param[in] request The current request.
* @param[in] rctx created by #unlang_module.
* @param[in] action to signal.
*/
static void unlang_xlat_signal(REQUEST *request, void *rctx, fr_state_signal_t action)
{
unlang_stack_t *stack = request->stack;
unlang_stack_frame_t *frame = &stack->frame[stack->depth];
unlang_resume_t *mr = unlang_generic_to_resume(frame->instruction);
unlang_frame_state_xlat_t *xs = talloc_get_type_abort(frame->state, unlang_frame_state_xlat_t);

rad_assert(stack->depth > 0);

if (!mr->signal) return;

xlat_signal((xlat_func_signal_t)mr->signal, xs->exp, request, rctx, action);
}

/** Called when we're ready to resume processing the request
*
* @param[in] request to resume processing.
Expand All @@ -328,13 +353,13 @@ static unlang_action_t unlang_xlat_resume(REQUEST *request, rlm_rcode_t *presult
{
unlang_stack_t *stack = request->stack;
unlang_stack_frame_t *frame = &stack->frame[stack->depth];
unlang_t *instruction = frame->instruction;
unlang_resume_t *mr = unlang_generic_to_resume(instruction);
unlang_resume_t *mr = unlang_generic_to_resume(frame->instruction);
unlang_frame_state_xlat_t *xs = talloc_get_type_abort(frame->state, unlang_frame_state_xlat_t);
xlat_action_t xa;

xa = xlat_frame_eval_resume(xs->ctx, &xs->values, (xlat_func_resume_t)mr->callback,
xs->exp, request, &xs->rhead, rctx);
xa = xlat_frame_eval_resume(xs->ctx, &xs->values,
(xlat_func_resume_t)mr->callback, xs->exp,
request, &xs->rhead, rctx);
switch (xa) {
case XLAT_ACTION_YIELD:
*presult = RLM_MODULE_YIELD;
Expand Down Expand Up @@ -397,6 +422,7 @@ void unlang_xlat_init(void)
.name = "xlat_eval",
.func = unlang_xlat,
.resume = unlang_xlat_resume,
.signal = unlang_xlat_signal,
.debug_braces = false
});

Expand Down

0 comments on commit a110751

Please sign in to comment.