From: Olivier Houchard Date: Thu, 2 Jul 2026 14:50:28 +0000 (+0200) Subject: MEDIUM: pollers: Create the poller pipes before we create the thread X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=5f548bc8e63f68e7a1daaf211ac67d0b4c57f9d7;p=thirdparty%2Fhaproxy.git MEDIUM: pollers: Create the poller pipes before we create the thread 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. --- diff --git a/include/haproxy/fd.h b/include/haproxy/fd.h index f993c6bbc..d06777b33 100644 --- a/include/haproxy/fd.h +++ b/include/haproxy/fd.h @@ -96,6 +96,8 @@ void poller_pipe_io_handler(int fd); */ int init_pollers(void); +int fd_precreate_poller_pipes(void); + /* * Deinitialize the pollers. */ diff --git a/src/fd.c b/src/fd.c index 9c851fe07..66e256cd6 100644 --- 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]; 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.