From 4fdec7aafaca0b7e67a7c9782a6599004d1d3bc6 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Thu, 11 Oct 2018 17:09:14 +0200 Subject: [PATCH] BUG/MEDIUM: stream: Make sure to unsubscribe before si_release_endpoint. 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 | 6 +++++- src/stream.c | 18 +++--------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h index e83187b4d..95a8e2317 100644 --- a/include/proto/stream_interface.h +++ b/include/proto/stream_interface.h @@ -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); diff --git a/src/stream.c b/src/stream.c index 97c4d9bb5..a57879d86 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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 */