MINOR: threads: serialize threads initialization

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.
diff --git a/src/haproxy.c b/src/haproxy.c
index 9c93bed..2417917 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -2572,6 +2572,15 @@
 	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 @@
 		}
 	}
 
-	/* 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)