]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: stream: Make sure to unsubscribe before si_release_endpoint.
authorOlivier Houchard <ohouchard@haproxy.com>
Thu, 11 Oct 2018 15:09:14 +0000 (17:09 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 11 Oct 2018 15:16:43 +0000 (17:16 +0200)
Make sure we unsubscribe from events before si_release_endpoint destroys
the conn_stream, or it will be never called. To do so, move the call to
unsubscribe to si_release_endpoint() directly.

This is 1.9-specific and shouldn't be backported.

include/proto/stream_interface.h
src/stream.c

index e83187b4de548dd8a0e9dc2c2c8d6a466d532d90..95a8e2317359258349bdf802ab15ed62f241c428 100644 (file)
@@ -169,8 +169,12 @@ static inline void si_release_endpoint(struct stream_interface *si)
        if (!si->end)
                return;
 
-       if ((cs = objt_cs(si->end)))
+       if ((cs = objt_cs(si->end))) {
+               if (si->wait_event.wait_reason != 0)
+                       cs->conn->mux->unsubscribe(cs, si->wait_event.wait_reason,
+                           &si->wait_event);
                cs_destroy(cs);
+       }
        else if ((appctx = objt_appctx(si->end))) {
                if (appctx->applet->release && si->state < SI_ST_DIS)
                        appctx->applet->release(appctx);
index 97c4d9bb5809e5296d4aa674c4d5a58cd100d01e..a57879d861d9b966e733f882b214801282115130 100644 (file)
@@ -400,27 +400,15 @@ static void stream_free(struct stream *s)
        /* applets do not release session yet */
        must_free_sess = objt_appctx(sess->origin) && sess->origin == s->si[0].end;
 
+       tasklet_free(s->si[0].wait_event.task);
+       tasklet_free(s->si[1].wait_event.task);
+
        si_release_endpoint(&s->si[1]);
        si_release_endpoint(&s->si[0]);
 
        if (must_free_sess)
                session_free(sess);
 
-       tasklet_free(s->si[0].wait_event.task);
-       if (s->si[0].wait_event.wait_reason != 0) {
-               struct conn_stream *cs = objt_cs(s->si[0].end);
-               if (cs)
-                       cs->conn->mux->unsubscribe(cs, s->si[0].wait_event.wait_reason,
-                           &s->si[0].wait_event);
-       }
-       tasklet_free(s->si[1].wait_event.task);
-       if (s->si[1].wait_event.wait_reason != 0) {
-               struct conn_stream *cs = objt_cs(s->si[1].end);
-               if (cs)
-                       cs->conn->mux->unsubscribe(cs, s->si[1].wait_event.wait_reason,
-                           &s->si[1].wait_event);
-       }
-
        pool_free(pool_head_stream, s);
 
        /* We may want to free the maximum amount of pools if the proxy is stopping */