]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: listener: Consider maxconn before waking listeners
authorOlivier Houchard <ohouchard@haproxy.com>
Tue, 6 Oct 2026 12:42:47 +0000 (14:42 +0200)
committerOlivier Houchard <cognet@ci0.org>
Tue, 6 Oct 2026 12:44:50 +0000 (14:44 +0200)
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.

src/listener.c

index 37866287a6dd0a06be352d2a2a9469f0eaffc2bd..1c46303d8222e63194f5f7fa9aaaca34f576ade8 100644 (file)
@@ -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.
                 */