[libdispatch-dev] [patch] workaround for GNU/Linux pthread_exit() bug
Mark Heily
mark at heily.com
Sun May 15 18:12:37 PDT 2011
See below for a patch to dispatch_main() that is needed on GNU/Linux. This
platform cannot call pthread_exit() from the main thread because of an
undocumented bug that causes the process to become a zombie. As an
alternative, this patch manually calls the TSD destructors, blocks all
signals, and parks the main thread using pause().
If there is anything else that needs to be done to make this a viable
alternative to calling pthread_exit(), please let me know.
Regards,
- Mark
$ svn di src/queue.c
Index: src/queue.c
===================================================================
--- src/queue.c (revision 197)
+++ src/queue.c (working copy)
@@ -941,8 +941,32 @@
if (pthread_main_np()) {
#endif
_dispatch_program_is_probably_callback_driven = true;
+#if defined(__linux__)
+ /*
+ * Workaround for a GNU/Linux bug that causes the process to
+ * become a zombie when the main thread calls pthread_exit().
+ */
+ sigset_t mask;
+ void *p;
+
+ p = pthread_getspecific(dispatch_queue_key);
+ if (p != NULL)
+ _dispatch_queue_cleanup(p);
+ p = pthread_getspecific(dispatch_sema4_key);
+ if (p != NULL)
+ _dispatch_release(p);
+ p = pthread_getspecific(dispatch_cache_key);
+ if (p != NULL)
+ _dispatch_cache_cleanup2(p);
+
+ sigfillset(&mask);
+ pthread_sigmask(SIG_SETMASK, &mask, NULL);
+ pause();
+ DISPATCH_CRASH("pause() returned");
+#else /* !defined(__linux__) */
pthread_exit(NULL);
DISPATCH_CRASH("pthread_exit() returned");
+#endif
#if HAVE_PTHREAD_MAIN_NP
}
DISPATCH_CLIENT_CRASH("dispatch_main() must be called on the main thread");
More information about the libdispatch-dev
mailing list