BUG/MEDIUM: threads: Atomically set TH_FL_SLEEPING and clr FL_NOTIFIED

When we're about to enter polling, atomically set TH_FL_SLEEPING and
remove TH_FL_NOTIFIED, instead of doing it in sequence. Otherwise,
another thread may sett that both the TH_FL_SLEEPING and the
TH_FL_NOTIFIED bits are set, and don't wake up the thread then it should
be doing that.
This prevents a bug where a thread is sleeping while it should be
handling a new connection, which can happen if there are very few
incoming connection. This is easy to reproduce when using only two
threads, and injecting with only one connection, the connection may then
never be handled.

This should be backported up to 2.8.
This commit is contained in:
Olivier Houchard 2026-02-04 01:46:36 +00:00
parent 2527d9dcd1
commit 3674afe8a0

View File

@ -2918,9 +2918,12 @@ void run_poll_loop()
if (thread_has_tasks())
activity[tid].wake_tasks++;
else {
_HA_ATOMIC_OR(&th_ctx->flags, TH_FL_SLEEPING);
_HA_ATOMIC_AND(&th_ctx->flags, ~TH_FL_NOTIFIED);
__ha_barrier_atomic_store();
unsigned int flags = _HA_ATOMIC_LOAD(&th_ctx->flags);
while (unlikely(!HA_ATOMIC_CAS(&th_ctx->flags, &flags,
(flags | TH_FL_SLEEPING) & ~TH_FL_NOTIFIED)))
__ha_cpu_relax();
if (thread_has_tasks()) {
activity[tid].wake_tasks++;
_HA_ATOMIC_AND(&th_ctx->flags, ~TH_FL_SLEEPING);