mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-02-04 17:01:24 +01:00
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:
parent
2527d9dcd1
commit
3674afe8a0
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user