From: Christopher Faulet Date: Tue, 10 Nov 2026 15:13:17 +0000 (+0100) Subject: MINOR: mux-spop: ignore conn->owner when deciding if a connection is dead X-Git-Url: https://git.kaiwu.me/%7B@url%7D?a=commitdiff_plain;h=d1fd7ba478fa605ec0e553b08464f24aad6ec6fe;p=haproxy.git MINOR: mux-spop: ignore conn->owner when deciding if a connection is dead spop_conn_is_dead() reports a connection as dead when it has no stream left and conn->owner is NULL, on the assumption that an ownerless connection has nobody left to take care of it. This no longer holds since idle backend connections are stored in the server and may legitimately have conn->owner NULL while still being usable. The same test was removed from h2c_is_dead() by commit a0541f5d2 ("BUG/MEDIUM: mux-h2: ignore conn->owner when deciding if a connection is dead") and from fcgi_conn_is_dead() by commit 170a6469c ("BUG/MEDIUM: mux-fcgi: ignore conn->owner when deciding if a connection is dead"). In the SPOP mux, spop_conn_is_dead() is only called at the end of spop_detach(), which is never reached for an idle connection moved to an idle list, and the stream test makes the predicate false as long as streams remain. So the test has no visible effect for now. But it prevents the dead connection check from being performed before the idle list management, the non-private branch clearing conn->owner before parking the connection. So let's remove it. This may be backported to 3.1. --- diff --git a/src/mux_spop.c b/src/mux_spop.c index dc6b439e1..7d4087087 100644 --- a/src/mux_spop.c +++ b/src/mux_spop.c @@ -847,7 +847,6 @@ static inline int spop_conn_is_dead(struct spop_conn *spop_conn) ((spop_conn->flags & SPOP_CF_ERROR) || /* errors close immediately */ (spop_conn->flags & SPOP_CF_ERR_PENDING && spop_conn->state < SPOP_CS_RUNNING) || /* early error during connect */ (spop_conn->state == SPOP_CS_CLOSED && !spop_conn->task) ||/* a timeout stroke earlier */ - (!(spop_conn->conn->owner)) || /* Nobody's left to take care of the connection, drop it now */ (!br_data(spop_conn->mbuf) && /* mux buffer empty, also process clean events below */ (spop_conn->flags & SPOP_CF_RCVD_SHUT)))) return 1;