]> Savannah Git Hosting - gnulib.git/commitdiff
setlocale-null: Remove need for -lpthread on musl libc, *BSD, Haiku.
authorBruno Haible <bruno@clisp.org>
Mon, 16 Dec 2019 09:38:37 +0000 (10:38 +0100)
committerBruno Haible <bruno@clisp.org>
Mon, 16 Dec 2019 09:44:58 +0000 (10:44 +0100)
Reported by Arnold Robbins <arnold@skeeve.com>.

* lib/setlocale_null.c (c11_threads_in_use, pthread_in_use): New macros,
copied from lib/glthread/lock.h.
(pthread_mutex_lock, pthread_mutex_unlock): Mark as weak.
(setlocale_null_with_lock): If pthread_in_use() is false, use
setlocale_null_unlocked directly.
* m4/threadlib.m4 (gl_WEAK_SYMBOLS): New macro, extracted from
gl_THREADLIB_BODY. Define HAVE_WEAK_SYMBOLS.
(gl_THREADLIB_BODY): Invoke gl_WEAK_SYMBOLS.
* m4/setlocale_null.m4 (gl_FUNC_SETLOCALE_NULL): Invoke gl_WEAK_SYMBOLS.
Set LIB_SETLOCALE_NULL to empty if weak symbols are supported.
* m4/duplocale.m4 (gl_FUNC_DUPLOCALE): Add comment.

ChangeLog
lib/setlocale_null.c
m4/duplocale.m4
m4/setlocale_null.m4
m4/threadlib.m4

index 8766995f6daac4f3066e317369800277f0f728fc..237bfdda1b3d527edd5c5e736645f36f2ac1d588 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2019-12-16  Bruno Haible  <bruno@clisp.org>
+
+       setlocale-null: Remove need for -lpthread on musl libc, *BSD, Haiku.
+       Reported by Arnold Robbins <arnold@skeeve.com>.
+       * lib/setlocale_null.c (c11_threads_in_use, pthread_in_use): New macros,
+       copied from lib/glthread/lock.h.
+       (pthread_mutex_lock, pthread_mutex_unlock): Mark as weak.
+       (setlocale_null_with_lock): If pthread_in_use() is false, use
+       setlocale_null_unlocked directly.
+       * m4/threadlib.m4 (gl_WEAK_SYMBOLS): New macro, extracted from
+       gl_THREADLIB_BODY. Define HAVE_WEAK_SYMBOLS.
+       (gl_THREADLIB_BODY): Invoke gl_WEAK_SYMBOLS.
+       * m4/setlocale_null.m4 (gl_FUNC_SETLOCALE_NULL): Invoke gl_WEAK_SYMBOLS.
+       Set LIB_SETLOCALE_NULL to empty if weak symbols are supported.
+       * m4/duplocale.m4 (gl_FUNC_DUPLOCALE): Add comment.
+
 2019-12-16  Paul Eggert  <eggert@cs.ucla.edu>
 
        dfa: make dfasyntax thread-safe
index b0506b9a1250efda8c04fa244993840ca710b4cb..350eca7299af2453460a6b50ada6a6659d671796 100644 (file)
 
 #if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE)
 # if defined _WIN32 && !defined __CYGWIN__
+
 #  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
 #  include <windows.h>
+
 # elif HAVE_PTHREAD_API
+
 #  include <pthread.h>
+#  if HAVE_THREADS_H && HAVE_WEAK_SYMBOLS
+#   include <threads.h>
+#   pragma weak thrd_exit
+#   define c11_threads_in_use() (thrd_exit != NULL)
+#  else
+#   define c11_threads_in_use() 0
+#  endif
+
 # elif HAVE_THREADS_H
+
 #  include <threads.h>
+
 # endif
 #endif
 
@@ -100,7 +113,7 @@ setlocale_null_unlocked (int category, char *buf, size_t bufsize)
 #endif
 }
 
-#if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE)
+#if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE) /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin */
 
 /* Use a lock, so that no two threads can invoke setlocale_null_unlocked
    at the same time.  */
@@ -125,7 +138,7 @@ setlocale_null_with_lock (int category, char *buf, size_t bufsize)
   return ret;
 }
 
-# elif HAVE_PTHREAD_API
+# elif HAVE_PTHREAD_API /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin */
 
 extern
 #  if defined _WIN32 || defined __CYGWIN__
@@ -133,19 +146,40 @@ extern
 #  endif
   pthread_mutex_t *gl_get_setlocale_null_lock (void);
 
+#  if HAVE_WEAK_SYMBOLS /* musl libc, FreeBSD, NetBSD, OpenBSD, Haiku */
+
+    /* Avoid the need to link with '-lpthread'.  */
+#   pragma weak pthread_mutex_lock
+#   pragma weak pthread_mutex_unlock
+
+    /* Determine whether libpthread is in use.  */
+#   pragma weak pthread_mutexattr_gettype
+    /* See the comments in lock.h.  */
+#   define pthread_in_use() \
+      (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
+
+#  else
+#   define pthread_in_use() 1
+#  endif
+
 static int
 setlocale_null_with_lock (int category, char *buf, size_t bufsize)
 {
-  pthread_mutex_t *lock = gl_get_setlocale_null_lock ();
-  int ret;
+  if (pthread_in_use())
+    {
+      pthread_mutex_t *lock = gl_get_setlocale_null_lock ();
+      int ret;
 
-  if (pthread_mutex_lock (lock))
-    abort ();
-  ret = setlocale_null_unlocked (category, buf, bufsize);
-  if (pthread_mutex_unlock (lock))
-    abort ();
+      if (pthread_mutex_lock (lock))
+        abort ();
+      ret = setlocale_null_unlocked (category, buf, bufsize);
+      if (pthread_mutex_unlock (lock))
+        abort ();
 
-  return ret;
+      return ret;
+    }
+  else
+    return setlocale_null_unlocked (category, buf, bufsize);
 }
 
 # elif HAVE_THREADS_H
index 3900b53b5e88e03b9839f04c14decc662cb33836..a2ac467780e2361cf59b1d2ffd8c5769b09cdf8e 100644 (file)
@@ -115,6 +115,8 @@ int main ()
   else
     LIB_DUPLOCALE=
   fi
+  dnl LIB_DUPLOCALE is expected to be '-pthread' or '-lpthread' on AIX
+  dnl with gcc or xlc, and empty otherwise.
   AC_SUBST([LIB_DUPLOCALE])
 ])
 
index 5c69a3f5ce2e89805f6702be57cdb53a139a8c15..eff6e76ab6548caa16d1ea2c880b32e1f507fc33 100644 (file)
@@ -1,4 +1,4 @@
-# setlocale_null.m4 serial 1
+# setlocale_null.m4 serial 2
 dnl Copyright (C) 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,
@@ -75,10 +75,18 @@ AC_DEFUN([gl_FUNC_SETLOCALE_NULL],
   if test $SETLOCALE_NULL_ALL_MTSAFE = 0 || test $SETLOCALE_NULL_ONE_MTSAFE = 0; then
     case "$host_os" in
       mingw*) LIB_SETLOCALE_NULL= ;;
-      *)      LIB_SETLOCALE_NULL="$LIBPTHREAD" ;;
+      *)
+        gl_WEAK_SYMBOLS
+        case "$gl_cv_have_weak" in
+          *yes) LIB_SETLOCALE_NULL= ;;
+          *)    LIB_SETLOCALE_NULL="$LIBPTHREAD" ;;
+        esac
+        ;;
     esac
   else
     LIB_SETLOCALE_NULL=
   fi
+  dnl LIB_SETLOCALE_NULL is expected to be '-pthread' or '-lpthread' on AIX
+  dnl with gcc or xlc, and empty otherwise.
   AC_SUBST([LIB_SETLOCALE_NULL])
 ])
index d6e6bf99716c6c16e1ef5a13cff0c390c3998de0..96c74c18b300c79de6608e52beaa52ca536e02bb 100644 (file)
@@ -1,4 +1,4 @@
-# threadlib.m4 serial 23
+# threadlib.m4 serial 24
 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,
@@ -142,6 +142,57 @@ changequote([,])dnl
   fi
 ])
 
+dnl Checks whether the compiler and linker support weak declarations of symbols.
+
+AC_DEFUN([gl_WEAK_SYMBOLS],
+[
+  AC_CACHE_CHECK([whether imported symbols can be declared weak],
+    [gl_cv_have_weak],
+    [gl_cv_have_weak=no
+     dnl First, test whether the compiler accepts it syntactically.
+     AC_LINK_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[extern void xyzzy ();
+#pragma weak xyzzy]],
+          [[xyzzy();]])],
+       [gl_cv_have_weak=maybe])
+     if test $gl_cv_have_weak = maybe; then
+       dnl Second, test whether it actually works. On Cygwin 1.7.2, with
+       dnl gcc 4.3, symbols declared weak always evaluate to the address 0.
+       AC_RUN_IFELSE(
+         [AC_LANG_SOURCE([[
+#include <stdio.h>
+#pragma weak fputs
+int main ()
+{
+  return (fputs == NULL);
+}]])],
+         [gl_cv_have_weak=yes],
+         [gl_cv_have_weak=no],
+         [dnl When cross-compiling, assume that only ELF platforms support
+          dnl weak symbols.
+          AC_EGREP_CPP([Extensible Linking Format],
+            [#ifdef __ELF__
+             Extensible Linking Format
+             #endif
+            ],
+            [gl_cv_have_weak="guessing yes"],
+            [gl_cv_have_weak="guessing no"])
+         ])
+     fi
+     dnl But when linking statically, weak symbols don't work.
+     case " $LDFLAGS " in
+       *" -static "*) gl_cv_have_weak=no ;;
+     esac
+    ])
+  case "$gl_cv_have_weak" in
+    *yes)
+      AC_DEFINE([HAVE_WEAK_SYMBOLS], [1],
+        [Define to 1 if the compiler and linker support weak declarations of symbols.])
+      ;;
+  esac
+])
+
 dnl The guts of gl_PTHREADLIB. Needs to be expanded only once.
 
 AC_DEFUN([gl_PTHREADLIB_BODY],
@@ -242,45 +293,7 @@ AC_DEFUN([gl_THREADLIB_BODY],
   LTLIBMULTITHREAD=
   if test "$gl_use_threads" != no; then
     dnl Check whether the compiler and linker support weak declarations.
-    AC_CACHE_CHECK([whether imported symbols can be declared weak],
-      [gl_cv_have_weak],
-      [gl_cv_have_weak=no
-       dnl First, test whether the compiler accepts it syntactically.
-       AC_LINK_IFELSE(
-         [AC_LANG_PROGRAM(
-            [[extern void xyzzy ();
-#pragma weak xyzzy]],
-            [[xyzzy();]])],
-         [gl_cv_have_weak=maybe])
-       if test $gl_cv_have_weak = maybe; then
-         dnl Second, test whether it actually works. On Cygwin 1.7.2, with
-         dnl gcc 4.3, symbols declared weak always evaluate to the address 0.
-         AC_RUN_IFELSE(
-           [AC_LANG_SOURCE([[
-#include <stdio.h>
-#pragma weak fputs
-int main ()
-{
-  return (fputs == NULL);
-}]])],
-           [gl_cv_have_weak=yes],
-           [gl_cv_have_weak=no],
-           [dnl When cross-compiling, assume that only ELF platforms support
-            dnl weak symbols.
-            AC_EGREP_CPP([Extensible Linking Format],
-              [#ifdef __ELF__
-               Extensible Linking Format
-               #endif
-              ],
-              [gl_cv_have_weak="guessing yes"],
-              [gl_cv_have_weak="guessing no"])
-           ])
-       fi
-       dnl But when linking statically, weak symbols don't work.
-       case " $LDFLAGS " in
-         *" -static "*) gl_cv_have_weak=no ;;
-       esac
-      ])
+    gl_WEAK_SYMBOLS
     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 /
       dnl thread_in_use, we also need to test whether the ISO C 11 thrd_create