Skip to content

Commit febea9e

Browse files
committed
Linux: avoid zombie process when dispatch_main is called
If the main thread calls pthread_exit on Linux, the process becomes a zombie. Modify dispatch_main to avoid this by adding a pthread_key destructor that calls dispatch_sig_thread (effectively stalling pthread exit until the program really exits). This patch relies on the TSD destructors being called in order of creation, which is currently the case in glibc.
1 parent 92689ed commit febea9e

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

src/queue.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#define pthread_workqueue_t void*
4949
#endif
5050

51+
static void _dispatch_sig_thread(void *ctxt);
5152
static void _dispatch_cache_cleanup(void *value);
5253
static void _dispatch_sync_f(dispatch_queue_t dq, void *ctxt,
5354
dispatch_function_t func, pthread_priority_t pp);
@@ -5693,6 +5694,11 @@ dispatch_main(void)
56935694
_dispatch_object_debug(&_dispatch_main_q, "%s", __func__);
56945695
_dispatch_program_is_probably_callback_driven = true;
56955696
_dispatch_ktrace0(ARIADNE_ENTER_DISPATCH_MAIN_CODE);
5697+
#ifdef __linux__
5698+
pthread_key_t dispatch_main_key;
5699+
pthread_key_create(&dispatch_main_key, _dispatch_sig_thread);
5700+
pthread_setspecific(dispatch_main_key, &dispatch_main_key); // anything non NULL really
5701+
#endif
56965702
pthread_exit(NULL);
56975703
DISPATCH_INTERNAL_CRASH(errno, "pthread_exit() returned");
56985704
#if HAVE_PTHREAD_MAIN_NP
@@ -5776,11 +5782,13 @@ _dispatch_queue_cleanup2(void)
57765782
// overload the "probably" variable to mean that dispatch_main() or
57775783
// similar non-POSIX API was called
57785784
// this has to run before the DISPATCH_COCOA_COMPAT below
5785+
#ifndef __linux__
57795786
if (_dispatch_program_is_probably_callback_driven) {
57805787
_dispatch_barrier_async_detached_f(_dispatch_get_root_queue(
57815788
_DISPATCH_QOS_CLASS_DEFAULT, true), NULL, _dispatch_sig_thread);
57825789
sleep(1); // workaround 6778970
57835790
}
5791+
#endif
57845792

57855793
#if DISPATCH_COCOA_COMPAT
57865794
dispatch_once_f(&_dispatch_main_q_port_pred, dq,

0 commit comments

Comments
 (0)