]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-h2: immediately remove a failed connection from the idle list
authorWilly Tarreau <w@1wt.eu>
Thu, 31 Oct 2019 14:36:30 +0000 (15:36 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 31 Oct 2019 14:39:27 +0000 (15:39 +0100)
If a connection faces an error or a timeout, it must be removed from its
idle list ASAP. We certainly don't want to risk sending new streams on
it.

This should be backported to 2.0 (replacing MT_LIST_DEL with LIST_DEL_LOCKED)
and 1.9 (there's no lock there, the idle lists are per-thread and per-server
however a LIST_DEL_INIT will be needed).

src/mux_h2.c

index 22bf42919bac059b9aab62b53f5d4dfbd4556c40..c9b805bb3cb511da6c03c528c725968b3ce8b12f 100644 (file)
@@ -3626,6 +3626,17 @@ static int h2_process(struct h2c *h2c)
                        TRACE_DEVEL("leaving after releasing the connection", H2_EV_H2C_WAKE);
                        return -1;
                }
+
+               /* connections in error must be removed from the idle lists */
+               HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]);
+               MT_LIST_DEL((struct mt_list *)&conn->list);
+               HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
+       }
+       else if (h2c->st0 == H2_CS_ERROR) {
+               /* connections in error must be removed from the idle lists */
+               HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]);
+               MT_LIST_DEL((struct mt_list *)&conn->list);
+               HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
        }
 
        if (!b_data(&h2c->dbuf))
@@ -3733,6 +3744,11 @@ static struct task *h2_timeout_task(struct task *t, void *context, unsigned shor
                        offer_buffers(NULL, tasks_run_queue);
        }
 
+       /* in any case this connection must not be considered idle anymore */
+       HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]);
+       MT_LIST_DEL((struct mt_list *)&h2c->conn->list);
+       HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
+
        /* either we can release everything now or it will be done later once
         * the last stream closes.
         */