Index: libdispatch-0~svn197/configure.ac
===================================================================
--- libdispatch-0~svn197.orig/configure.ac	2011-06-28 22:06:58.000000000 -0400
+++ libdispatch-0~svn197/configure.ac	2011-06-28 22:07:19.000000000 -0400
@@ -8,6 +8,7 @@
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_HEADER([config/config.h])
 AC_CONFIG_MACRO_DIR([m4])
+AC_PROG_CC([clang gcc cc])
 AC_USE_SYSTEM_EXTENSIONS
 AM_MAINTAINER_MODE
 
@@ -112,7 +113,6 @@
 )
 
 AC_USE_SYSTEM_EXTENSIONS
-AC_PROG_CC
 AC_PROG_CXX
 AC_PROG_INSTALL
 AC_PROG_LIBTOOL
Index: libdispatch-0~svn197/m4/private-extern.m4
===================================================================
--- libdispatch-0~svn197.orig/m4/private-extern.m4	2011-06-28 22:06:52.000000000 -0400
+++ libdispatch-0~svn197/m4/private-extern.m4	2011-06-28 22:07:19.000000000 -0400
@@ -19,6 +19,17 @@
                     [dispatch_cv_private_extern=yes],
                     [dispatch_cv_private_extern=no])])
 
+case $host_os in
+*gnu*)
+  #
+  # WORKAROUND: Building with clang and the GNU linker causes this error:
+  #
+  # /usr/bin/ld: .libs/libdispatch_la-apply.o: relocation R_X86_64_PC32 against symbol `_dispatch_hw_config' can not be used when making a shared object; recompile with -fPIC
+  #
+  AC_DEFINE([__private_extern__], [extern],
+	    [Define to a replacement for __private_extern])
+  ;;
+*)
 if test $dispatch_cv_private_extern = yes; then
   AC_DEFINE(HAVE_PRIVATE_EXTERN, 1, Define if __private_extern__ present)
 elif test $dispatch_cv_hidden_visibility_attribute = yes; then
@@ -29,5 +40,6 @@
   AC_DEFINE([__private_extern__], [extern],
 	    [Define to a replacement for __private_extern])
 fi
-
+;;
+esac
 ])
Index: libdispatch-0~svn197/src/queue.c
===================================================================
--- libdispatch-0~svn197.orig/src/queue.c	2011-06-28 22:07:04.000000000 -0400
+++ libdispatch-0~svn197/src/queue.c	2011-06-28 22:07:19.000000000 -0400
@@ -23,6 +23,8 @@
 #include "protocol.h"
 #endif
 
+static void _dispatch_queue_cleanup(void *ctxt);
+
 void
 dummy_function(void)
 {
@@ -377,7 +379,7 @@
 		// The first xchg on the tail will tell the enqueueing thread that it
 		// is safe to blindly write out to the head pointer. A cmpxchg honors
 		// the algorithm.
-		dispatch_atomic_cmpxchg(&dq->dq_items_head, mediator, NULL);
+		(void) dispatch_atomic_cmpxchg(&dq->dq_items_head, mediator, NULL);
 		_dispatch_debug("no work on global work queue");
 		return NULL;
 	}
@@ -474,12 +476,13 @@
 	    _dispatch_hw_config.cc_max_physical =
 	    _dispatch_hw_config.cc_max_active;
 #elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
-	_dispatch_hw_config.cc_max_active = (int)sysconf(_SC_NPROCESSORS_ONLN);
-	if (_dispatch_hw_config.cc_max_active < 0)
-		_dispatch_hw_config.cc_max_active = 1;
+    int ret;
+    
+	ret = (int)sysconf(_SC_NPROCESSORS_ONLN);
+
 	_dispatch_hw_config.cc_max_logical =
 	    _dispatch_hw_config.cc_max_physical =
-	    _dispatch_hw_config.cc_max_active;
+	    _dispatch_hw_config.cc_max_active = (ret < 0) ? 1 : ret;
 #else
 #warning "_dispatch_queue_set_width_init: no supported way to query CPU count"
 	_dispatch_hw_config.cc_max_logical =
@@ -941,8 +944,33 @@
 	if (pthread_main_np()) {
 #endif
 		_dispatch_program_is_probably_callback_driven = true;
-		pthread_exit(NULL);
-		DISPATCH_CRASH("pthread_exit() returned");
+#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);
+        for (;;) {
+            pause();
+        }
+#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");
