From 17cc4e468452008b6a2bc72c19511c11896199f6 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Fri, 9 Feb 2024 15:08:55 +0100 Subject: [PATCH] BUG/MINOR: applet: Always release empty appctx buffers after processing 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 | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/applet.c b/src/applet.c index 984ff2661..014759041 100644 --- a/src/applet.c +++ b/src/applet.c @@ -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 * 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; }