From 9cb11d0859dffb670f5cdc70ecdbd43ff43f14f0 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 12 Mar 2026 09:05:14 +0100 Subject: [PATCH] MINOR: applet: set execution context on applet calls It allows to know when a thread is currnetly running inside an applet. For example now "show threads" will show "applet ''" for the thread issuing this command. --- include/haproxy/applet.h | 9 ++++++++- include/haproxy/tinfo-t.h | 2 ++ src/applet.c | 13 ++++++------- src/tools.c | 3 +++ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/haproxy/applet.h b/include/haproxy/applet.h index e36b1d5ed..1604b87d5 100644 --- a/include/haproxy/applet.h +++ b/include/haproxy/applet.h @@ -62,6 +62,13 @@ ssize_t applet_append_line(void *ctx, struct ist v1, struct ist v2, size_t ofs, static forceinline void applet_fl_set(struct appctx *appctx, uint on); static forceinline void applet_fl_clr(struct appctx *appctx, uint off); +/* macros to switch the calling context to the applet during a call. There's + * one with a return value for most calls, and one without for the few like + * fct(), shut(), or release() with no return. + */ +#define CALL_APPLET_WITH_RET(applet, func) EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_APPLET, (applet)), (applet)->func) +#define CALL_APPLET_NO_RET(applet, func) EXEC_CTX_NO_RET(EXEC_CTX_MAKE(TH_EX_CTX_APPLET, (applet)), (applet)->func) + static forceinline uint appctx_app_test(const struct appctx *appctx, uint test) { @@ -126,7 +133,7 @@ static inline int appctx_init(struct appctx *appctx) task_set_thread(appctx->t, tid); if (appctx->applet->init) - return appctx->applet->init(appctx); + return CALL_APPLET_WITH_RET(appctx->applet, init(appctx)); return 0; } diff --git a/include/haproxy/tinfo-t.h b/include/haproxy/tinfo-t.h index bf9108cb8..a17527e79 100644 --- a/include/haproxy/tinfo-t.h +++ b/include/haproxy/tinfo-t.h @@ -88,6 +88,7 @@ enum thread_exec_ctx_type { TH_EX_CTX_FLT, /* filter whose config is in .flt_conf */ TH_EX_CTX_MUX, /* mux whose mux_ops is in .mux_ops */ TH_EX_CTX_TASK, /* task or tasklet whose function is in .task */ + TH_EX_CTX_APPLET, /* applet whose applet is in .applet */ }; struct thread_exec_ctx { @@ -103,6 +104,7 @@ struct thread_exec_ctx { const struct flt_conf *flt_conf; /* used with TH_EX_CTX_FLTCONF */ const struct mux_ops *mux_ops; /* used with TH_EX_CTX_MUX */ const struct task *(*task)(struct task *, void *, unsigned int); /* used with TH_EX_CTX_TASK */ + const struct applet *applet; /* used with TH_EX_CTX_APPLET */ }; }; diff --git a/src/applet.c b/src/applet.c index 58909b8a2..4246da3e4 100644 --- a/src/applet.c +++ b/src/applet.c @@ -31,7 +31,6 @@ unsigned int nb_applets = 0; DECLARE_TYPED_POOL(pool_head_appctx, "appctx", struct appctx); - /* trace source and events */ static void applet_trace(enum trace_level level, uint64_t mask, const struct trace_source *src, @@ -417,7 +416,7 @@ void appctx_shut(struct appctx *appctx) TRACE_ENTER(APPLET_EV_RELEASE, appctx); if (appctx->applet->release) - appctx->applet->release(appctx); + CALL_APPLET_NO_RET(appctx->applet, release(appctx)); applet_fl_set(appctx, APPCTX_FL_SHUTDOWN); b_dequeue(&appctx->buffer_wait); @@ -551,7 +550,7 @@ size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsig if (flags & CO_RFL_BUF_FLUSH) applet_fl_set(appctx, APPCTX_FL_FASTFWD); - ret = appctx->applet->rcv_buf(appctx, buf, count, flags); + ret = CALL_APPLET_WITH_RET(appctx->applet, rcv_buf(appctx, buf, count, flags)); if (ret) applet_fl_clr(appctx, APPCTX_FL_OUTBLK_FULL); @@ -659,7 +658,7 @@ size_t appctx_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, unsig goto end; } - ret = appctx->applet->snd_buf(appctx, buf, count, flags); + ret = CALL_APPLET_WITH_RET(appctx->applet, snd_buf(appctx, buf, count, flags)); if (applet_fl_test(appctx, (APPCTX_FL_ERROR|APPCTX_FL_ERR_PENDING))) se_report_term_evt(appctx->sedesc, se_tevt_type_snd_err); @@ -716,7 +715,7 @@ int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags) } b_add(sdo->iobuf.buf, sdo->iobuf.offset); - ret = appctx->applet->fastfwd(appctx, sdo->iobuf.buf, len, 0); + ret = CALL_APPLET_WITH_RET(appctx->applet, fastfwd(appctx, sdo->iobuf.buf, len, 0)); b_sub(sdo->iobuf.buf, sdo->iobuf.offset); sdo->iobuf.data += ret; @@ -853,7 +852,7 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state) * already called) */ if (!se_fl_test(app->sedesc, SE_FL_SHR) || !se_fl_test(app->sedesc, SE_FL_SHW)) - app->applet->fct(app); + CALL_APPLET_NO_RET(app->applet, fct(app)); TRACE_POINT(APPLET_EV_PROCESS, app); @@ -954,7 +953,7 @@ struct task *task_process_applet(struct task *t, void *context, unsigned int sta * already called) */ if (!applet_fl_test(app, APPCTX_FL_SHUTDOWN)) - app->applet->fct(app); + CALL_APPLET_NO_RET(app->applet, fct(app)); TRACE_POINT(APPLET_EV_PROCESS, app); diff --git a/src/tools.c b/src/tools.c index e58f44c53..08dd48074 100644 --- a/src/tools.c +++ b/src/tools.c @@ -7552,6 +7552,9 @@ void chunk_append_thread_ctx(struct buffer *output, const struct thread_exec_ctx resolve_sym_name(output, "task '", ctx->task); chunk_appendf(output,"'"); break; + case TH_EX_CTX_APPLET: + chunk_appendf(output,"applet '%s'", ctx->applet->name); + break; default: chunk_appendf(output,"other ctx %p", ctx->pointer); break;