From: Olivier Houchard Date: Sun, 22 Mar 2020 18:56:03 +0000 (+0100) Subject: BUG/MEDIUM: h1: Make sure we subscribe before going into idle list. X-Git-Tag: v2.2-dev5~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3c49c1bd5ce1b47baa63d3c4058437e341389d98;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: h1: Make sure we subscribe before going into idle list. In h1_detach(), make sure we subscribe before we call srv_add_to_idle_list(), not after. As soon as srv_add_to_idle_list() is called, and it is put in an idle list, another thread can take it, and we're no longer allowed to subscribe. This fixes a race condition when another thread grabs a connection as soon as it is put, the original owner would subscribe, and thus the new thread would fail to do so, and to activate polling. --- diff --git a/src/mux_h1.c b/src/mux_h1.c index f4cf0ff84c..fee645b191 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -2466,13 +2466,13 @@ static void h1_detach(struct conn_stream *cs) if (!(h1c->conn->flags & CO_FL_PRIVATE)) { if (h1c->conn->owner == sess) h1c->conn->owner = NULL; + h1c->conn->xprt->subscribe(h1c->conn, h1c->conn->xprt_ctx, SUB_RETRY_RECV, &h1c->wait_event); if (!srv_add_to_idle_list(objt_server(h1c->conn->target), h1c->conn, is_not_first)) { /* The server doesn't want it, let's kill the connection right away */ h1c->conn->mux->destroy(h1c); TRACE_DEVEL("outgoing connection killed", H1_EV_STRM_END|H1_EV_H1C_END); goto end; } - h1c->conn->xprt->subscribe(h1c->conn, h1c->conn->xprt_ctx, SUB_RETRY_RECV, &h1c->wait_event); return; } }