]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
Revert "MEDIUM: queue: unlock as soon as possible"
authorWilly Tarreau <w@1wt.eu>
Thu, 24 Jun 2021 05:21:59 +0000 (07:21 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 24 Jun 2021 05:21:59 +0000 (07:21 +0200)
This reverts commit 5b3927531145384bad8d2b46ca21f017afde81c7.

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 e16331f6d2a8a2f2184e80f59854a0fb4f82f3c1..8db2da2c04568cba8bc4bbc079692c67528e3a7d 100644 (file)
@@ -270,23 +270,20 @@ static struct pendconn *pendconn_process_next_strm(struct server *srv, struct pr
        u32 pkey, ppkey;
 
        p = NULL;
-       if (srv->queue.length) {
-               HA_SPIN_LOCK(QUEUE_LOCK, &srv->queue.lock);
+       HA_SPIN_LOCK(QUEUE_LOCK, &srv->queue.lock);
+       if (srv->queue.length)
                p = pendconn_first(&srv->queue.head);
-               if (!p)
-                       HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
-       }
 
        pp = NULL;
-       if (px_ok && px->queue.length) {
-               HA_SPIN_LOCK(QUEUE_LOCK, &px->queue.lock);
+       HA_SPIN_LOCK(QUEUE_LOCK, &px->queue.lock);
+       if (px_ok && px->queue.length)
                pp = pendconn_first(&px->queue.head);
-               if (!pp)
-                       HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
-       }
 
-       if (!p && !pp)
+       if (!p && !pp) {
+               HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
+               HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
                return NULL;
+       }
        else if (!pp)
                goto use_p; /*  p != NULL */
        else if (!p)
@@ -314,18 +311,16 @@ static struct pendconn *pendconn_process_next_strm(struct server *srv, struct pr
 
  use_pp:
        /* Let's switch from the server pendconn to the proxy pendconn */
-       if (p)
-               HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
        __pendconn_unlink_prx(pp);
        HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
+       HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
        _HA_ATOMIC_INC(&px->queue.idx);
        _HA_ATOMIC_DEC(&px->queue.length);
        _HA_ATOMIC_DEC(&px->totpend);
        p = pp;
        goto unlinked;
  use_p:
-       if (pp)
-               HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
+       HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
        __pendconn_unlink_srv(p);
        HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
        _HA_ATOMIC_INC(&srv->queue.idx);