]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: tasks: don't type-pun state and tid in builds without threads
authorOlivier Houchard <ohouchard@haproxy.com>
Fri, 14 Aug 2026 14:33:10 +0000 (16:33 +0200)
committerOlivier Houchard <cognet@ci0.org>
Fri, 14 Aug 2026 14:27:04 +0000 (16:27 +0200)
__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
src/thread.c

index 801bc6dfe734d3c94a55c8c02e63699f265cf347..37342900751b89fee1a5bd7926b94d41061a9aef 100644 (file)
@@ -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);
 
index 3a6efe48264683aa4b7fe1989acefcda6991ac35..557af60fb9202222c15a201ea72471ff360d0d9b 100644 (file)
@@ -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.