From: Willy Tarreau Date: Thu, 24 Jun 2021 13:51:12 +0000 (+0200) Subject: BUG: backend: stop looking for queued connections once there's no more X-Git-Tag: v2.5-dev1~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=19c5581b43eb07c3e413cf1be076bd0b2c2becc7;p=thirdparty%2Fhaproxy.git BUG: backend: stop looking for queued connections once there's no more Commit ae0b12ee0 ("MEDIUM: queue: use a trylock on the server's queue") introduced a hard to trigger bug that's more visible with a single thread: if a server dequeues a connection and finds another free slot with no connection to place there, process_srv_queue() will never break out of the loop. In multi-thread it almost does not happen because other threads bring new connections. No backport is needed as it's only in -dev. --- diff --git a/src/queue.c b/src/queue.c index b7610d41bd..b7ca163ebb 100644 --- a/src/queue.c +++ b/src/queue.c @@ -330,6 +330,7 @@ void process_srv_queue(struct server *s) struct server *ref = s->track ? s->track : s; struct proxy *p = s->proxy; int maxconn; + int stop = 0; int done = 0; int px_ok; @@ -345,13 +346,13 @@ void process_srv_queue(struct server *s) * for the same server will give up, knowing that at least one of * them will check the conditions again before quitting. */ - while (s->served < (maxconn = srv_dynamic_maxconn(s))) { + while (!stop && s->served < (maxconn = srv_dynamic_maxconn(s))) { if (HA_SPIN_TRYLOCK(SERVER_LOCK, &s->queue.lock) != 0) break; while (s->served < maxconn) { - int ret = pendconn_process_next_strm(s, p, px_ok); - if (!ret) + stop = !pendconn_process_next_strm(s, p, px_ok); + if (stop) break; _HA_ATOMIC_INC(&s->served); done++;