]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG: backend: stop looking for queued connections once there's no more
authorWilly Tarreau <w@1wt.eu>
Thu, 24 Jun 2021 13:51:12 +0000 (15:51 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 24 Jun 2021 13:56:07 +0000 (15:56 +0200)
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.

src/queue.c

index b7610d41bda6c674af73ff4a4cd05f7f7f5a1688..b7ca163ebb667331aebf8617e815c91389f2f350 100644 (file)
@@ -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++;