]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: applet: Add dedicated IN/OUT buffers for appctx
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 8 Jan 2024 07:05:59 +0000 (08:05 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 7 Feb 2024 14:03:01 +0000 (15:03 +0100)
It is the first patch of a series aimed to align applets on connections.
Here, dedicated buffers are added for applets. For now, buffers are
initialized and helpers function to deal with allocation are added. In
addition, flags to report allocation failures or full buffers are also
introduced. <inbuf> will be used to push data to the applet from the stream
and <outbuf> will be used to push data from the applet to the stream.

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

index bd96403c58648c3aeb05c792d158a12b52df7602..0ee4fbc3413981a0ce95245aa60172e0474e7ac2 100644 (file)
 
 /* flags for appctx->state */
 #define APPLET_WANT_DIE     0x01  /* applet was running and requested to die */
+#define APPLET_INBLK_ALLOC  0x02
+#define APPLET_INBLK_FULL   0x04
+#define APPLET_OUTBLK_ALLOC 0x08
+#define APPLET_OUTBLK_FULL  0x10
 
 /* Room for per-command context (mostly CLI commands but not only) */
 #define APPLET_MAX_SVCCTX 88
@@ -60,6 +64,10 @@ struct appctx {
        unsigned short state;      /* Internal appctx state */
        unsigned int st0;          /* CLI state for stats, session state for peers */
        unsigned int st1;          /* prompt/payload (bitwise OR of APPCTX_CLI_ST1_*) for stats, session error for peers */
+
+       struct buffer inbuf;
+       struct buffer outbuf;
+
        struct buffer *chunk;       /* used to store unfinished commands */
        struct applet *applet;     /* applet this context refers to */
        struct session *sess;      /* session for frontend applets (NULL for backend applets) */
index b04ffd95caf17a90930e8e1cd29ef44ab5fcd1d1..9cc50c305f1cfc5ff73bf9406ddb081cd8a1d594 100644 (file)
@@ -58,6 +58,35 @@ static inline struct appctx *appctx_new_anywhere(struct applet *applet, struct s
        return appctx_new_on(applet, sedesc, -1);
 }
 
+
+/*
+ * Release a buffer, if any, and try to wake up entities waiting in the buffer
+ * wait queue.
+ */
+static inline void appctx_release_buf(struct appctx *appctx, struct buffer *bptr)
+{
+       if (bptr->size) {
+               b_free(bptr);
+               offer_buffers(appctx->buffer_wait.target, 1);
+       }
+}
+
+/*
+ * Allocate a buffer. If if fails, it adds the appctx in buffer wait queue.
+ */
+static inline struct buffer *appctx_get_buf(struct appctx *appctx, struct buffer *bptr)
+{
+       struct buffer *buf = NULL;
+
+       if (likely(!LIST_INLIST(&appctx->buffer_wait.list)) &&
+           unlikely((buf = b_alloc(bptr)) == NULL)) {
+               appctx->buffer_wait.target = appctx;
+               appctx->buffer_wait.wakeup_cb = appctx_buf_available;
+               LIST_APPEND(&th_ctx->buffer_wq, &appctx->buffer_wait.list);
+       }
+       return buf;
+}
+
 /* Helper function to call .init applet callback function, if it exists. Returns 0
  * on success and -1 on error.
  */
@@ -78,6 +107,9 @@ static inline int appctx_init(struct appctx *appctx)
 /* Releases an appctx previously allocated by appctx_new(). */
 static inline void __appctx_free(struct appctx *appctx)
 {
+       appctx_release_buf(appctx, &appctx->inbuf);
+       appctx_release_buf(appctx, &appctx->outbuf);
+
        task_destroy(appctx->t);
        if (LIST_INLIST(&appctx->buffer_wait.list))
                LIST_DEL_INIT(&appctx->buffer_wait.list);
index 5e6312efee1335eac4038cf0de118a2c2de4b2be..71e21c23d3a030c61db27a4b8e907d3de8111437 100644 (file)
@@ -232,6 +232,9 @@ struct appctx *appctx_new_on(struct applet *applet, struct sedesc *sedesc, int t
        appctx->t->process = task_run_applet;
        appctx->t->context = appctx;
 
+       appctx->inbuf = BUF_NULL;
+       appctx->outbuf = BUF_NULL;
+
        LIST_INIT(&appctx->buffer_wait.list);
        appctx->buffer_wait.target = appctx;
        appctx->buffer_wait.wakeup_cb = appctx_buf_available;
@@ -379,6 +382,18 @@ int appctx_buf_available(void *arg)
        struct appctx *appctx = arg;
        struct stconn *sc = appctx_sc(appctx);
 
+       if ((appctx->state & APPLET_INBLK_ALLOC) && b_alloc(&appctx->inbuf)) {
+               appctx->state &= ~APPLET_INBLK_ALLOC;
+               task_wakeup(appctx->t, TASK_WOKEN_RES);
+               return 1;
+       }
+
+       if ((appctx->state & APPLET_OUTBLK_ALLOC) && b_alloc(&appctx->outbuf)) {
+               appctx->state &= ~APPLET_OUTBLK_ALLOC;
+               task_wakeup(appctx->t, TASK_WOKEN_RES);
+               return 1;
+       }
+
        /* allocation requested ? */
        if (!(sc->flags & SC_FL_NEED_BUFF))
                return 0;