[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
setlocale-null: remove need for -lpthread on musl libc, *BSD, Haiku
From: |
Bruno Haible |
Subject: |
setlocale-null: remove need for -lpthread on musl libc, *BSD, Haiku |
Date: |
Mon, 16 Dec 2019 10:42:26 +0100 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-166-generic; KDE/5.18.0; x86_64; ; ) |
This patch removes the need to link with -lpthread on several platforms,
by using the "weak symbols" trick from lock.h. With this, the only platform
on which setlocale-null requires -lpthread is AIX.
2019-12-16 Bruno Haible <address@hidden>
setlocale-null: Remove need for -lpthread on musl libc, *BSD, Haiku.
Reported by Arnold Robbins <address@hidden>.
* 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.
diff --git a/lib/setlocale_null.c b/lib/setlocale_null.c
index b0506b9..350eca7 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 3900b53..a2ac467 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 5c69a3f..eff6e76 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 d6e6bf9..96c74c1 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
- new module 'setlocale-null', Bruno Haible, 2019/12/15
- setlocale-null: remove need for -lpthread on musl libc, *BSD, Haiku,
Bruno Haible <=
- Re: new module 'setlocale-null', Bruno Haible, 2019/12/18
- Re: new module 'setlocale-null', Bruno Haible, 2019/12/22
- Re: new module 'setlocale-null', Bruno Haible, 2019/12/23
- Re: new module 'setlocale-null', Bruno Haible, 2019/12/24