]> git.kaiwu.me - haproxy.git/commitdiff
MEDIUM: stream: Hold a reference on the frontend during stream_free()
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 8 Oct 2026 10:22:10 +0000 (12:22 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 9 Oct 2026 14:17:36 +0000 (16:17 +0200)
The frontend of a stream is dereferenced until the end of stream_free(), in
particular to flush the maximum amount of pools when the proxy is stopping.
But when the stream connectors are destroyed, a client applet attached to
the stream is released there, and it may free its internal frontend (created
owned by the applet), leaving the end of the function with a dangling
frontend.

Take a reference on the frontend before releasing the stream connector and
drop it at the very end of stream_free(), after the last dereference of the
frontend. For the frontends that are never released during the lifetime of
the process, this is a balanced pair of reference counter updates.

This will be needed by the next commits, adding a destroy callback to the
applet ops, called when an applet context is destroyed, which may release
the frontend of its applet stream.

src/stream.c

index c04571df03c6a61dfc3aecfbbc7a624139923ad7..4c425230f286a97d5bf17fb91268bb02a9da7613 100644 (file)
@@ -738,6 +738,15 @@ void stream_free(struct stream *s)
                                pool_free(h->pool, s->res_cap[h->index]);
                        pool_free(fe->rsp_cap_pool, s->res_cap);
                }
+
+               /* Hold a reference on the frontend for the rest of the stream
+                * teardown. The stream connectors are destroyed below. An
+                * client applet attached to the stream will be released there,
+                * and it may free an internal frontend (created and owned by an
+                * applet), leaving the end of the function with a dangling
+                * frontend. The reference is dropped at the very end.
+                */
+               proxy_take(fe);
        }
 
        /* Cleanup all variable contexts. */
@@ -799,6 +808,8 @@ void stream_free(struct stream *s)
                pool_flush(fe->req_cap_pool);
                pool_flush(fe->rsp_cap_pool);
        }
+
+       proxy_drop(fe);
 }