]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: applet: Always release empty appctx buffers after processing
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 9 Feb 2024 14:08:55 +0000 (15:08 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 9 Feb 2024 14:14:38 +0000 (15:14 +0100)
When an applet is using its own buffers, it is important to release them, if
empty, after processing to recycle unsued buffers. It is not a leak because
these buffers are necessarily released when the applet is released. But this
leads to an excess of buffer allocations.

No need to backport.

src/applet.c

index 984ff2661bd54b0e01637000cfe05f0cf9acb0f9..0147590416aa5330277caba2406005092e028954 100644 (file)
@@ -410,6 +410,29 @@ void appctx_shut(struct appctx *appctx)
        TRACE_LEAVE(APPLET_EV_RELEASE, appctx);
 }
 
+/* releases unused buffers after processing. It will try to wake up as many
+ * entities as the number of buffers that it releases.
+ */
+static void appctx_release_buffers(struct appctx * appctx)
+{
+       int offer = 0;
+
+       if (b_size(&appctx->inbuf) && !b_data(&appctx->inbuf)) {
+               offer++;
+               b_free(&appctx->inbuf);
+       }
+       if (b_size(&appctx->outbuf) && !b_data(&appctx->outbuf)) {
+               offer++;
+               b_free(&appctx->outbuf);
+       }
+
+       /* if we're certain to have at least 1 buffer available, and there is
+        * someone waiting, we can wake up a waiter and offer them.
+        */
+       if (offer)
+               offer_buffers(appctx, offer);
+}
+
 /* Callback used to wake up an applet when a buffer is available. The applet
  * <appctx> is woken up if an input buffer was requested for the associated
  * stream connector. In this case the buffer is immediately allocated and the
@@ -866,6 +889,7 @@ struct task *task_process_applet(struct task *t, void *context, unsigned int sta
        }
 
        sc->app_ops->wake(sc);
+       appctx_release_buffers(app);
        TRACE_LEAVE(APPLET_EV_PROCESS, app);
        return t;
 }