summaryrefslogtreecommitdiff
path: root/lib/setlocale_null.c
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 /lib/setlocale_null.c
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.
Diffstat (limited to 'lib/setlocale_null.c')
-rw-r--r--lib/setlocale_null.c54
1 files changed, 44 insertions, 10 deletions
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