[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