From 67a218c536ea9df14dbfdf5f4d8c208b64e2225d Mon Sep 17 00:00:00 2001
From: Roland McGrath <mcgrathr@google.com>
Date: Mon, 11 Jun 2012 21:15:38 +0000
Subject: [PATCH] gthr-posix.h [...] (__gthread_active_p): If __GLIBC__ is
 defined, refer to __pthread_key_create instead of pthread_cancel.

	* gthr-posix.h [neither FreeBSD nor Solaris] (__gthread_active_p):
	If __GLIBC__ is defined, refer to __pthread_key_create instead of
	pthread_cancel.

From-SVN: r188400
---
 libgcc/ChangeLog    |  6 ++++++
 libgcc/gthr-posix.h | 41 +++++++++++++++++++++++++++++++++--------
 2 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index dd1dc5504a5a..d2093daa9de5 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,9 @@
+2012-06-11  Roland McGrath  <mcgrathr@google.com>
+
+	* gthr-posix.h [neither FreeBSD nor Solaris] (__gthread_active_p):
+	If __GLIBC__ is defined, refer to __pthread_key_create instead of
+	pthread_cancel.
+
 2012-06-09  Uros Bizjak  <ubizjak@gmail.com>
 
 	* config/i386/32/sfp-machine.h (__gcc_CMPtype, CMPtype,
diff --git a/libgcc/gthr-posix.h b/libgcc/gthr-posix.h
index b5b161184f45..cc4e518f5b99 100644
--- a/libgcc/gthr-posix.h
+++ b/libgcc/gthr-posix.h
@@ -212,18 +212,43 @@ __gthread_active_p (void)
 
 #else /* neither FreeBSD nor Solaris */
 
+/* For a program to be multi-threaded the only thing that it certainly must
+   be using is pthread_create.  However, there may be other libraries that
+   intercept pthread_create with their own definitions to wrap pthreads
+   functionality for some purpose.  In those cases, pthread_create being
+   defined might not necessarily mean that libpthread is actually linked
+   in.
+
+   For the GNU C library, we can use a known internal name.  This is always
+   available in the ABI, but no other library would define it.  That is
+   ideal, since any public pthread function might be intercepted just as
+   pthread_create might be.  __pthread_key_create is an "internal"
+   implementation symbol, but it is part of the public exported ABI.  Also,
+   it's among the symbols that the static libpthread.a always links in
+   whenever pthread_create is used, so there is no danger of a false
+   negative result in any statically-linked, multi-threaded program.
+
+   For others, we choose pthread_cancel as a function that seems unlikely
+   to be redefined by an interceptor library.  The bionic (Android) C
+   library does not provide pthread_cancel, so we do use pthread_create
+   there (and interceptor libraries lose).  */
+
+#ifdef __GLIBC__
+__gthrw2(__gthrw_(__pthread_key_create),
+	 __pthread_key_create,
+	 pthread_key_create)
+# define GTHR_ACTIVE_PROXY	__gthrw_(__pthread_key_create)
+#elif defined (__BIONIC__)
+# define GTHR_ACTIVE_PROXY	__gthrw_(pthread_create)
+#else
+# define GTHR_ACTIVE_PROXY	__gthrw_(pthread_cancel)
+#endif
+
 static inline int
 __gthread_active_p (void)
 {
-/* Android's C library does not provide pthread_cancel, check for
-   `pthread_create' instead.  */
-#ifndef __BIONIC__
   static void *const __gthread_active_ptr
-    = __extension__ (void *) &__gthrw_(pthread_cancel);
-#else
-  static void *const __gthread_active_ptr
-    = __extension__ (void *) &__gthrw_(pthread_create);
-#endif
+    = __extension__ (void *) &GTHR_ACTIVE_PROXY;
   return __gthread_active_ptr != 0;
 }
 
-- 
GitLab