[libdispatch-dev] [patch] workaround for GNU/Linux pthread_exit() bug
Marius Zwicker
marius at mlba-team.de
Tue May 17 11:12:40 PDT 2011
That's fairly interesting. I had to do this change a while ago as
Windows does not know tls destructors at all. Oddly enough I experienced
issues on some versions of Linux only. The latest incarnation of Open
SuSe 64bit (11.4 I think) had issues, but only when executing C++ code
before calling dispatch_main() whereas Ubuntu 10.10 made no problems at
all. The change below fixed that behaviour as well.
I consider your patch quite necessary as it - as a side effect - will
increase the readability of the code. Someone taking a first glance at
the code will have no way to understand how a call to pthread_exit() can
cause a worker for the main queue to emerge. When seing the destructors
getting called it is a lot easier.
- Marius
Am 16.05.2011 03:12, schrieb Mark Heily:
> 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");
> _______________________________________________
> libdispatch-dev mailing list
> libdispatch-dev at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/libdispatch-dev
More information about the libdispatch-dev
mailing list