]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: applet: set execution context on applet calls
authorWilly Tarreau <w@1wt.eu>
Thu, 12 Mar 2026 08:05:14 +0000 (09:05 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 12 Mar 2026 17:06:38 +0000 (18:06 +0100)
It allows to know when a thread is currnetly running inside an applet.
For example now "show threads" will show "applet '<CLI>'" for the thread
issuing this command.

include/haproxy/applet.h
include/haproxy/tinfo-t.h
src/applet.c
src/tools.c

index e36b1d5ed67577c055da7cc7e4a980a78ab49eca..1604b87d5124b79cfffae0630852cca6da76cfce 100644 (file)
@@ -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;
 }
 
index bf9108cb855171349c6adbe135a8a8837e08a791..a17527e79aa5d50b3b46c07d09f1682b7f40826c 100644 (file)
@@ -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 */
        };
 };
 
index 58909b8a269e5f0aeeb3259b661638d379541ca0..4246da3e48a3a8ec06c3e3917aa0e9c835e81d54 100644 (file)
@@ -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);
 
index e58f44c538622ccab3559854df0e04ba315fc934..08dd480746e53cf8bc79d17b0d269be65f31bea2 100644 (file)
@@ -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;