From c5f41118c01db4babcf6919f5eae4ce308adcfef Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Fri, 14 Aug 2026 16:33:10 +0200 Subject: [PATCH] BUG/MEDIUM: tasks: don't type-pun state and tid in builds without threads __task_set_state_and_tid() updates t->state and t->tid at once through an uint64_t cast, which violates strict aliasing. With threads the __atomic builtins keep the compiler conservative, but without them the accesses are plain, and gcc -O2 legitimately keeps using a stale t->state: the CAS always fails and _task_wakeup() spins forever on the first request until the watchdog kills the process. Without threads there is no concurrency to protect against, so just compare and assign the two fields directly. --- src/haproxy.c | 12 ------------ src/thread.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/haproxy.c b/src/haproxy.c index 801bc6dfe..373429007 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -3946,18 +3946,6 @@ int main(int argc, char **argv) } } - /* When FD tables are not shared between thread groups, the poller - * pipes of all threads must be created before any group unshares its - * FD table, so that they are inherited into every group's table and - * cross-group wake_thread() keeps working. This must be done for all - * builds, including those without threads, since each thread will pick - * its own pair from there. - */ - if (!fd_precreate_poller_pipes()) { - ha_alert("Failed to create the poller pipes.\n"); - exit(1); - } - /* start threads 2 and above */ setup_extra_threads(&run_thread_poll_loop); diff --git a/src/thread.c b/src/thread.c index 3a6efe482..557af60fb 100644 --- a/src/thread.c +++ b/src/thread.c @@ -278,6 +278,16 @@ void setup_extra_threads(void *(*handler)(void *)) /* the startup thread will be thread 1 */ ha_pthread[0] = pthread_self(); + /* When FD tables are not shared between thread groups, the poller + * pipes of all threads must be created before any group unshares its + * FD table, so that they are inherited into every group's table and + * cross-group wake_thread() keeps working. + */ + if (!fd_precreate_poller_pipes()) { + ha_alert("Failed to create the poller pipes.\n"); + exit(1); + } + /* Create one initial thread for each extra thread group. These will * each be responsible for creating their own extra threads. The first * group's initial thread is the current thread. -- 2.47.3