]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: init/mworker: make the pipe register function a regular initcall
authorWilly Tarreau <w@1wt.eu>
Mon, 20 May 2019 09:12:15 +0000 (11:12 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 20 May 2019 09:26:12 +0000 (11:26 +0200)
Now that we have the guarantee that init calls happen before any other
thread starts, we don't need anymore the workaround installed by commit
1605c7ae6 ("BUG/MEDIUM: threads/mworker: fix a race on startup") and we
can instead rely on a regular per-thread initcall for this function. It
will only be performed on worker thread #0, the other ones and the master
have nothing to do, just like in the original code that was only moved
to the function.

include/proto/mworker.h
src/haproxy.c
src/mworker.c

index 86f09049f53a8af0e85eb6d8f1bd143da3068eb6..2386a445ad47ee1329452761a8affbaca7ed7b4f 100644 (file)
@@ -27,7 +27,6 @@ void mworker_catch_sigterm(struct sig_handler *sh);
 void mworker_catch_sigchld(struct sig_handler *sh);
 
 void mworker_accept_wrapper(int fd);
-void mworker_pipe_register();
 
 void mworker_cleanlisteners();
 
index 2b3cf2ebf7c9fd3657758daa150f138d172d162a..661cbd1c115242d0ba26dc332f6446ea277d3c89 100644 (file)
@@ -2495,7 +2495,6 @@ static void *run_thread_poll_loop(void *data)
 {
        struct per_thread_init_fct   *ptif;
        struct per_thread_deinit_fct *ptdf;
-       __decl_hathreads(static HA_SPINLOCK_T start_lock);
 
        ha_set_tid((unsigned long)data);
        tv_update_date(-1,-1);
@@ -2511,12 +2510,6 @@ static void *run_thread_poll_loop(void *data)
                }
        }
 
-       if ((global.mode & MODE_MWORKER) && master == 0) {
-               HA_SPIN_LOCK(START_LOCK, &start_lock);
-               mworker_pipe_register();
-               HA_SPIN_UNLOCK(START_LOCK, &start_lock);
-       }
-
        /* broadcast that we are ready and wait for other threads to finish
         * their initialization.
         */
index cac74102cd8d28be1129eb5f43481951b24bfd6e..d5040b75990cbfcd58897269a1db1bc15c466ba3 100644 (file)
@@ -357,22 +357,29 @@ void mworker_accept_wrapper(int fd)
 }
 
 /*
- * This function register the accept wrapper for the sockpair of the master worker
+ * This function registers the accept wrapper for the sockpair of the master
+ * worker. It's only handled by worker thread #0. Other threads and master do
+ * nothing here. It always returns 1 (success).
  */
-void mworker_pipe_register()
+static int mworker_pipe_register_per_thread()
 {
-       /* The iocb should be already initialized with listener_accept */
-       if (fdtab[proc_self->ipc_fd[1]].iocb == mworker_accept_wrapper)
-               return;
+       if (!(global.mode & MODE_MWORKER) || master)
+               return 1;
+
+       if (tid != 0)
+               return 1;
 
        fcntl(proc_self->ipc_fd[1], F_SETFL, O_NONBLOCK);
        /* In multi-tread, we need only one thread to process
         * events on the pipe with master
         */
-       fd_insert(proc_self->ipc_fd[1], fdtab[proc_self->ipc_fd[1]].owner, mworker_accept_wrapper, 1);
+       fd_insert(proc_self->ipc_fd[1], fdtab[proc_self->ipc_fd[1]].owner, mworker_accept_wrapper, tid_bit);
        fd_want_recv(proc_self->ipc_fd[1]);
+       return 1;
 }
 
+REGISTER_PER_THREAD_INIT(mworker_pipe_register_per_thread);
+
 /* ----- proxies ----- */
 /*
  * Upon a reload, the master worker needs to close all listeners FDs but the mworker_pipe