From a3bf62ec541479531ebe93bde46b436cb95c9a87 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Thu, 28 Jan 2021 10:16:29 +0100 Subject: [PATCH] BUG/MINOR: backend: hold correctly lock when killing idle conn The wrong lock seems to be held when trying to remove another thread connection if max fd limit has been reached (locking the current thread instead of the target thread lock). This could be backported up to 2.0. --- src/backend.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backend.c b/src/backend.c index f6afde3..7a1d179 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1350,22 +1350,23 @@ int connect_server(struct stream *s) // see it possibly larger. ALREADY_CHECKED(i); - HA_SPIN_LOCK(OTHER_LOCK, &idle_conns[tid].takeover_lock); + HA_SPIN_LOCK(OTHER_LOCK, &idle_conns[i].takeover_lock); tokill_conn = MT_LIST_POP(&srv->idle_conns[i], struct connection *, list); if (!tokill_conn) tokill_conn = MT_LIST_POP(&srv->safe_conns[i], struct connection *, list); + if (tokill_conn) { /* We got one, put it into the concerned thread's to kill list, and wake it's kill task */ MT_LIST_ADDQ(&idle_conns[i].toremove_conns, (struct mt_list *)&tokill_conn->list); task_wakeup(idle_conns[i].cleanup_task, TASK_WOKEN_OTHER); - HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].takeover_lock); + HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[i].takeover_lock); break; } - HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].takeover_lock); + HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[i].takeover_lock); } } -- 1.7.10.4