]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
Revert "MEDIUM: queue: refine the locking in process_srv_queue()"
authorWilly Tarreau <w@1wt.eu>
Thu, 24 Jun 2021 05:26:57 +0000 (07:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 24 Jun 2021 07:55:14 +0000 (09:55 +0200)
This reverts commit 1b648c857bb9e0fb857e86838bcca0c9ed01e2bd.

The recent changes since 5304669e1 MEDIUM: queue: make
pendconn_process_next_strm() only return the pendconn opened a tiny race
condition between stream_free() and process_srv_queue(), as the pendconn
is accessed outside of the lock, possibly while it's being freed. A
different approach is required.

src/queue.c

index c9134afb92e0f4396c03dbbf056d2270a5043e25..d8e73b2181d9c562ed4e73e315e96a328517c219 100644 (file)
@@ -340,29 +340,27 @@ void process_srv_queue(struct server *s, int server_locked)
        int done = 0;
        int maxconn;
 
+       if (!server_locked)
+               HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK,  &p->lock);
        maxconn = srv_dynamic_maxconn(s);
        while (s->served < maxconn) {
                struct pendconn *pc;
 
-               if (!server_locked)
-                       HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
-               HA_RWLOCK_WRLOCK(PROXY_LOCK,  &p->lock);
-
                pc = pendconn_process_next_strm(s, p);
-
-               HA_RWLOCK_WRUNLOCK(PROXY_LOCK,  &p->lock);
-               if (!server_locked)
-                       HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
-
                if (!pc)
                        break;
 
                done++;
 
                _HA_ATOMIC_INC(&s->served);
+
                stream_add_srv_conn(pc->strm, s);
                task_wakeup(pc->strm->task, TASK_WOKEN_RES);
        }
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK,  &p->lock);
+       if (!server_locked)
+               HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
 
        _HA_ATOMIC_ADD(&p->served, done);