summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2019-12-16 10:38:37 +0100
committerBruno Haible <bruno@clisp.org>2019-12-16 10:44:58 +0100
commit6be2862414da45975b8cbc33acc5387b012f3354 (patch)
tree314f7a5917195baa3cb4de3efb547eb18d16803c
parentecb700c1c897e01f1c97f2f23c12ecb0d3658eba (diff)
downloadgnulib-6be2862414da45975b8cbc33acc5387b012f3354.tar.gz
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.
-rw-r--r--ChangeLog16
-rw-r--r--lib/setlocale_null.c54
-rw-r--r--m4/duplocale.m42
-rw-r--r--m4/setlocale_null.m412
-rw-r--r--m4/threadlib.m493
5 files changed, 125 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index 8766995f6d..237bfdda1b 100644
--- 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
diff --git a/lib/setlocale_null.c b/lib/setlocale_null.c
index b0506b9a12..350eca7299 100644
--- a/lib/setlocale_null.c
+++ b/lib/setlocale_null.c
@@ -30,12 +30,25 @@
#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
diff --git a/m4/duplocale.m4 b/m4/duplocale.m4
index 3900b53b5e..a2ac467780 100644
--- a/m4/duplocale.m4
+++ b/m4/duplocale.m4
@@ -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])
])
diff --git a/m4/setlocale_null.m4 b/m4/setlocale_null.m4
index 5c69a3f5ce..eff6e76ab6 100644
--- a/m4/setlocale_null.m4
+++ b/m4/setlocale_null.m4
@@ -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])
])
diff --git a/m4/threadlib.m4 b/m4/threadlib.m4
index d6e6bf9971..96c74c18b3 100644
--- a/m4/threadlib.m4
+++ b/m4/threadlib.m4
@@ -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