From 79c2545308000d2120009a76bea4f36f06f16b1b Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Thu, 20 Jun 2019 03:54:56 +0200
Subject: [PATCH] thread, lock, cond, tls: Recognize C11 multithreaded
 applications.

* m4/threadlib.m4 (gl_THREADLIB_BODY): Test for <threads.h>.
* lib/glthread/thread.h (c11_threads_in_use): New macro.
(pthread_in_use, pth_in_use, thread_in_use): Use it.
* lib/glthread/lock.h (c11_threads_in_use): New macro.
(pthread_in_use, pth_in_use, thread_in_use): Use it.
* lib/glthread/cond.h (c11_threads_in_use): New macro.
(pthread_in_use, pth_in_use, thread_in_use): Use it.
* lib/glthread/tls.h (c11_threads_in_use): New macro.
(pthread_in_use, pth_in_use, thread_in_use): Use it.
---
 ChangeLog             | 13 +++++++++++++
 lib/glthread/cond.h   | 18 +++++++++++++++---
 lib/glthread/lock.h   | 17 ++++++++++++++---
 lib/glthread/thread.h | 17 ++++++++++++++---
 lib/glthread/tls.h    | 17 ++++++++++++++---
 m4/threadlib.m4       |  9 ++++++++-
 6 files changed, 78 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b8ff877c14..a9fe91ef8f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2019-06-20  Bruno Haible  <bruno@clisp.org>
+
+	thread, lock, cond, tls: Recognize C11 multithreaded applications.
+	* m4/threadlib.m4 (gl_THREADLIB_BODY): Test for <threads.h>.
+	* lib/glthread/thread.h (c11_threads_in_use): New macro.
+	(pthread_in_use, pth_in_use, thread_in_use): Use it.
+	* lib/glthread/lock.h (c11_threads_in_use): New macro.
+	(pthread_in_use, pth_in_use, thread_in_use): Use it.
+	* lib/glthread/cond.h (c11_threads_in_use): New macro.
+	(pthread_in_use, pth_in_use, thread_in_use): Use it.
+	* lib/glthread/tls.h (c11_threads_in_use): New macro.
+	(pthread_in_use, pth_in_use, thread_in_use): Use it.
+
 2019-06-20  Bruno Haible  <bruno@clisp.org>
 
 	tls tests: Small improvements.
diff --git a/lib/glthread/cond.h b/lib/glthread/cond.h
index abfa7534c0..6540f1df8e 100644
--- a/lib/glthread/cond.h
+++ b/lib/glthread/cond.h
@@ -54,6 +54,17 @@
 #include <time.h>
 
 #include "glthread/lock.h"
+
+#if !defined c11_threads_in_use
+# if HAVE_THREADS_H && (USE_POSIX_THREADS_WEAK || USE_PTH_THREADS_WEAK || USE_SOLARIS_THREADS_WEAK)
+#  include <threads.h>
+#  pragma weak thrd_exit
+#  define c11_threads_in_use() (thrd_exit != NULL)
+# else
+#  define c11_threads_in_use() 0
+# endif
+#endif
+
 #ifndef _GL_INLINE_HEADER_BEGIN
  #error "Please include config.h first."
 #endif
@@ -115,7 +126,8 @@ extern int glthread_in_use (void);
 
 #  if !PTHREAD_IN_USE_DETECTION_HARD
 #   pragma weak pthread_mutexattr_gettype
-#   define pthread_in_use() (pthread_mutexattr_gettype != NULL)
+#   define pthread_in_use() \
+      (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
 #  endif
 
 # else
@@ -177,7 +189,7 @@ extern "C" {
 #  pragma weak pth_timeout
 
 #  pragma weak pth_cancel
-#  define pth_in_use() (pth_cancel != NULL)
+#  define pth_in_use() (pth_cancel != NULL || c11_threads_in_use ())
 
 # else
 
@@ -237,7 +249,7 @@ extern "C" {
 #  pragma weak cond_broadcast
 #  pragma weak cond_destroy
 #  pragma weak thr_suspend
-#  define thread_in_use() (thr_suspend != NULL)
+#  define thread_in_use() (thr_suspend != NULL || c11_threads_in_use ())
 
 # else
 
diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h
index 6e1fdf8c62..cc6fb5e60d 100644
--- a/lib/glthread/lock.h
+++ b/lib/glthread/lock.h
@@ -81,6 +81,16 @@
 #include <errno.h>
 #include <stdlib.h>
 
+#if !defined c11_threads_in_use
+# if HAVE_THREADS_H && (USE_POSIX_THREADS_WEAK || USE_PTH_THREADS_WEAK || USE_SOLARIS_THREADS_WEAK)
+#  include <threads.h>
+#  pragma weak thrd_exit
+#  define c11_threads_in_use() (thrd_exit != NULL)
+# else
+#  define c11_threads_in_use() 0
+# endif
+#endif
+
 /* ========================================================================= */
 
 #if USE_POSIX_THREADS
@@ -156,7 +166,8 @@ extern int glthread_in_use (void);
          pthread_rwlockattr_init
      */
 #   pragma weak pthread_mutexattr_gettype
-#   define pthread_in_use() (pthread_mutexattr_gettype != NULL)
+#   define pthread_in_use() \
+      (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
 #  endif
 
 # else
@@ -421,7 +432,7 @@ extern "C" {
 #  pragma weak pth_cond_notify
 
 #  pragma weak pth_cancel
-#  define pth_in_use() (pth_cancel != NULL)
+#  define pth_in_use() (pth_cancel != NULL || c11_threads_in_use ())
 
 # else
 
@@ -572,7 +583,7 @@ extern "C" {
 #  pragma weak thr_self
 
 #  pragma weak thr_suspend
-#  define thread_in_use() (thr_suspend != NULL)
+#  define thread_in_use() (thr_suspend != NULL || c11_threads_in_use ())
 
 # else
 
diff --git a/lib/glthread/thread.h b/lib/glthread/thread.h
index 1d2a544e24..f26312998c 100644
--- a/lib/glthread/thread.h
+++ b/lib/glthread/thread.h
@@ -74,6 +74,16 @@
 #include <errno.h>
 #include <stdlib.h>
 
+#if !defined c11_threads_in_use
+# if HAVE_THREADS_H && (USE_POSIX_THREADS_WEAK || USE_PTH_THREADS_WEAK || USE_SOLARIS_THREADS_WEAK)
+#  include <threads.h>
+#  pragma weak thrd_exit
+#  define c11_threads_in_use() (thrd_exit != NULL)
+# else
+#  define c11_threads_in_use() 0
+# endif
+#endif
+
 #ifndef _GL_INLINE_HEADER_BEGIN
  #error "Please include config.h first."
 #endif
@@ -148,7 +158,8 @@ extern int glthread_in_use (void);
 
 #  if !PTHREAD_IN_USE_DETECTION_HARD
 #   pragma weak pthread_mutexattr_gettype
-#   define pthread_in_use() (pthread_mutexattr_gettype != NULL)
+#   define pthread_in_use() \
+      (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
 #  endif
 
 # else
@@ -234,7 +245,7 @@ extern "C" {
 #  pragma weak pth_exit
 
 #  pragma weak pth_cancel
-#  define pth_in_use() (pth_cancel != NULL)
+#  define pth_in_use() (pth_cancel != NULL || c11_threads_in_use ())
 
 # else
 
@@ -287,7 +298,7 @@ extern "C" {
 #  pragma weak thr_exit
 
 #  pragma weak thr_suspend
-#  define thread_in_use() (thr_suspend != NULL)
+#  define thread_in_use() (thr_suspend != NULL || c11_threads_in_use ())
 
 # else
 
diff --git a/lib/glthread/tls.h b/lib/glthread/tls.h
index 399a879ea7..ab854091b5 100644
--- a/lib/glthread/tls.h
+++ b/lib/glthread/tls.h
@@ -46,6 +46,16 @@
 #include <errno.h>
 #include <stdlib.h>
 
+#if !defined c11_threads_in_use
+# if HAVE_THREADS_H && (USE_POSIX_THREADS_WEAK || USE_PTH_THREADS_WEAK || USE_SOLARIS_THREADS_WEAK)
+#  include <threads.h>
+#  pragma weak thrd_exit
+#  define c11_threads_in_use() (thrd_exit != NULL)
+# else
+#  define c11_threads_in_use() 0
+# endif
+#endif
+
 /* ========================================================================= */
 
 #if USE_POSIX_THREADS
@@ -77,7 +87,8 @@ extern int glthread_in_use (void);
 
 #  if !PTHREAD_IN_USE_DETECTION_HARD
 #   pragma weak pthread_mutexattr_gettype
-#   define pthread_in_use() (pthread_mutexattr_gettype != NULL)
+#   define pthread_in_use() \
+      (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
 #  endif
 
 # else
@@ -131,7 +142,7 @@ typedef union
 #  pragma weak pth_key_delete
 
 #  pragma weak pth_cancel
-#  define pth_in_use() (pth_cancel != NULL)
+#  define pth_in_use() (pth_cancel != NULL || c11_threads_in_use ())
 
 # else
 
@@ -183,7 +194,7 @@ typedef union
 #  pragma weak thr_setspecific
 
 #  pragma weak thr_suspend
-#  define thread_in_use() (thr_suspend != NULL)
+#  define thread_in_use() (thr_suspend != NULL || c11_threads_in_use ())
 
 # else
 
diff --git a/m4/threadlib.m4 b/m4/threadlib.m4
index b4401f8665..f02eb972cc 100644
--- a/m4/threadlib.m4
+++ b/m4/threadlib.m4
@@ -1,4 +1,4 @@
-# threadlib.m4 serial 17
+# threadlib.m4 serial 18
 dnl Copyright (C) 2005-2019 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -160,6 +160,13 @@ int main ()
          *" -static "*) gl_cv_have_weak=no ;;
        esac
       ])
+    if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+      dnl If we use weak symbols to implement pthread_in_use / pth_in_use /
+      gnl thread_in_use, we also need to test whether the ISO C 11 thrd_create
+      dnl facility is in use.
+      AC_CHECK_HEADERS_ONCE([threads.h])
+      :
+    fi
     if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
       # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
       # it groks <pthread.h>. It's added above, in gl_THREADLIB_EARLY_BODY.
-- 
2.39.5