]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: threads: serialize threads initialization
authorWilly Tarreau <w@1wt.eu>
Fri, 7 Jun 2019 12:41:11 +0000 (14:41 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 7 Jun 2019 13:37:47 +0000 (15:37 +0200)
There is no point in initializing threads in parallel when we know that
it's the moment where some global variables are turned to thread-local
ones, and/or that some global variables are updated (like global_now or
trash_size). Some FDs might be created/destroyed/reallocated and could
be tricky to follow as well (think about epoll_fd for example).

Instead of having to be extremely careful about all these, and to trigger
false positives in thread sanitizers, let's simply initialize one thread
at a time. The init step is very fast so nobody should even notice, and
we won't have any more doubts about what might have happened when
analysing a dump.

See GH issues #111 and #117 for some background on this.

src/haproxy.c

index 9c93bed33fac572002b72d8b171c76aa558f9e30..2417917c5cb5d6629625d2977215787b4b2073e7 100644 (file)
@@ -2572,6 +2572,15 @@ static void *run_thread_poll_loop(void *data)
        ti->clock_id = CLOCK_THREAD_CPUTIME_ID;
 #endif
 #endif
+       /* broadcast that we are ready and wait for other threads to start */
+       thread_release();
+
+       /* Now, initialize one thread init at a time. This is better since
+        * some init code is a bit tricky and may release global resources
+        * after reallocating them locally. This will also ensure there is
+        * no race on file descriptors allocation.
+        */
+       thread_isolate();
 
        tv_update_date(-1,-1);
 
@@ -2598,12 +2607,11 @@ static void *run_thread_poll_loop(void *data)
                }
        }
 
-       /* broadcast that we are ready and wait for other threads to finish
-        * their initialization.
-        */
+       protocol_enable_all();
+
+       /* done initializing this thread, wait for others */
        thread_release();
 
-       protocol_enable_all();
        run_poll_loop();
 
        list_for_each_entry(ptdf, &per_thread_deinit_list, list)