From: Olivier Houchard Date: Tue, 6 Oct 2026 12:42:47 +0000 (+0200) Subject: BUG/MEDIUM: listener: Consider maxconn before waking listeners X-Git-Tag: v3.5-dev9~192 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=4321fcc5591f7081b7caf75fc0ed97a5d40c5c86;p=haproxy.git BUG/MEDIUM: listener: Consider maxconn before waking listeners When dequeueing listeners in dequeue_all_listeners() and dequeue_proxy_listeners(), consider if we reached maxconn before doing so. If we do not, with enough thread groups, we may enter a state in which we dequeue listeners, try again to accept more connections, but that would fail, as maxconn would have been reached again by a different thread group, and we'd end up being stuck for long enough for the watchdog to trigger. This should be backported up to 2.8. This was submitted by Bruno Henc in github issue #3525. --- diff --git a/src/listener.c b/src/listener.c index 37866287a..1c46303d8 100644 --- a/src/listener.c +++ b/src/listener.c @@ -757,7 +757,8 @@ void dequeue_all_listeners() { struct listener *listener; - while ((listener = MT_LIST_POP(&global_listener_queue, struct listener *, wait_queue))) { + while (_HA_ATOMIC_LOAD(&actconn) < global.maxconn && + (listener = MT_LIST_POP(&global_listener_queue, struct listener *, wait_queue))) { /* This cannot fail because the listeners are by definition in * the LI_LIMITED state. */ @@ -774,7 +775,8 @@ void dequeue_proxy_listeners(struct proxy *px, int lpx) { struct listener *listener; - while ((listener = MT_LIST_POP(&px->listener_queue, struct listener *, wait_queue))) { + while (_HA_ATOMIC_LOAD(&px->feconn) < px->maxconn && + (listener = MT_LIST_POP(&px->listener_queue, struct listener *, wait_queue))) { /* This cannot fail because the listeners are by definition in * the LI_LIMITED state. */