]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: pollers: Create the poller pipes before we create the thread
authorOlivier Houchard <ohouchard@haproxy.com>
Thu, 2 Jul 2026 14:50:28 +0000 (16:50 +0200)
committerOlivier Houchard <cognet@ci0.org>
Thu, 30 Jul 2026 11:35:22 +0000 (13:35 +0200)
As we may now unshare the file descriptor tables, make sure we create
the pipes used to wake the pollers up before we create the threads, so
that they will be shared by all threads.

include/haproxy/fd.h
src/fd.c
src/thread.c

index f993c6bbc5ea1e20d517a4938d0ccd4bccf30b40..d06777b33bd4b2e04646f1fa72bbdf8efe164de5 100644 (file)
@@ -96,6 +96,8 @@ void poller_pipe_io_handler(int fd);
  */
 int init_pollers(void);
 
+int fd_precreate_poller_pipes(void);
+
 /*
  * Deinitialize the pollers.
  */
index 9c851fe07a9b285f2f7a76def25624430667fd3f..66e256cd6930a9b056db81fedc6c1e8945121df5 100644 (file)
--- a/src/fd.c
+++ b/src/fd.c
@@ -1147,12 +1147,37 @@ static int alloc_pollers_per_thread()
        return fd_updt != NULL;
 }
 
+static int precreated_poller_pipes[MAX_THREADS][2];
+
+/*
+ * Create the pipes before we create the threads, as they may not share
+ * their file descriptor tables.
+ */
+int fd_precreate_poller_pipes(void)
+{
+       int i;
+
+       for (i = 0; i < global.nbthread; i++) {
+               if (pipe(precreated_poller_pipes[i]) < 0)
+                       return 0;
+       }
+       return 1;
+}
+
 /* Initialize the pollers per thread.*/
 static int init_pollers_per_thread()
 {
        int mypipe[2];
 
-       if (pipe(mypipe) < 0)
+       /*
+        * The master does not get to pre-create pipes, so do it
+        * now.
+        */
+       if (!master) {
+               mypipe[0] = precreated_poller_pipes[tid][0];
+               mypipe[1] = precreated_poller_pipes[tid][1];
+       }
+       else if (pipe(mypipe) < 0)
                return 0;
 
        poller_rd_pipe = mypipe[0];
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.