Skip to content

Linux: avoid zombie process when dispatch_main is called #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 6, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define pthread_workqueue_t void*
#endif

static void _dispatch_sig_thread(void *ctxt);
static void _dispatch_cache_cleanup(void *value);
static void _dispatch_sync_f(dispatch_queue_t dq, void *ctxt,
dispatch_function_t func, pthread_priority_t pp);
Expand Down Expand Up @@ -5693,6 +5694,17 @@ dispatch_main(void)
_dispatch_object_debug(&_dispatch_main_q, "%s", __func__);
_dispatch_program_is_probably_callback_driven = true;
_dispatch_ktrace0(ARIADNE_ENTER_DISPATCH_MAIN_CODE);
#ifdef __linux__
// On Linux, if the main thread calls pthread_exit, the process becomes a zombie.
// To avoid that, just before calling pthread_exit we register a TSD destructor
// that will call _dispatch_sig_thread -- thus capturing the main thread in sigsuspend.
// This relies on an implementation detail (currently true in glibc) that TSD destructors
// will be called in the order of creation to cause all the TSD cleanup functions to
// run before the thread becomes trapped in sigsuspend.
pthread_key_t dispatch_main_key;
pthread_key_create(&dispatch_main_key, _dispatch_sig_thread);
pthread_setspecific(dispatch_main_key, &dispatch_main_key);
#endif
pthread_exit(NULL);
DISPATCH_INTERNAL_CRASH(errno, "pthread_exit() returned");
#if HAVE_PTHREAD_MAIN_NP
Expand Down Expand Up @@ -5776,11 +5788,14 @@ _dispatch_queue_cleanup2(void)
// overload the "probably" variable to mean that dispatch_main() or
// similar non-POSIX API was called
// this has to run before the DISPATCH_COCOA_COMPAT below
// See dispatch_main for call to _dispatch_sig_thread on linux.
#ifndef __linux__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here I would comment that Linux parks the main thread into sigsuspend hence this code is useless for this platform

if (_dispatch_program_is_probably_callback_driven) {
_dispatch_barrier_async_detached_f(_dispatch_get_root_queue(
_DISPATCH_QOS_CLASS_DEFAULT, true), NULL, _dispatch_sig_thread);
sleep(1); // workaround 6778970
}
#endif

#if DISPATCH_COCOA_COMPAT
dispatch_once_f(&_dispatch_main_q_port_pred, dq,
Expand Down