X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/1b96e9580714d7a677d10a8e286b3f8a2bddc6f5..c11f668ec9c5b2f0016cf6920a111c52e895b24a:/src/thread-posix.h diff --git a/src/thread-posix.h b/src/thread-posix.h index b1cd990..22378ed 100644 --- a/src/thread-posix.h +++ b/src/thread-posix.h @@ -8,6 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * + * The pthread_in_use detection is based on Gnulib code written by Bruno + * Haible, distributed with the following copyright and permission notice: + * + * Copyright (C) 2005-2022 Free Software Foundation, Inc. + * + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -19,6 +29,29 @@ #include +extern int glthread_in_use(); + +#if !defined c11_threads_in_use +# if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC +# define c11_threads_in_use 1 +# elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK +# include +# pragma weak thrd_exit +# define c11_threads_in_use (thrd_exit != NULL) +# else +# define c11_threads_in_use 0 +# endif +#endif + +#if PTHREAD_IN_USE_DETECTION_HARD +# define pthread_in_use glthread_in_use() +#elif USE_POSIX_THREADS_WEAK +# pragma weak pthread_mutexattr_gettype +# define pthread_in_use (pthread_mutexattr_gettype || c11_threads_in_use) +#else +# define pthread_in_use 1 +#endif + #if USE_POSIX_THREADS_WEAK # pragma weak pthread_key_create # pragma weak pthread_getspecific @@ -41,13 +74,7 @@ static struct { } tls_key; #define tls_key_valid (tls_key.valid != 0) -static void tls_key_init(void) -{ - if (pthread_in_use()) - tls_key.valid = !pthread_key_create(&tls_key.u.mt, free); - else - tls_key.valid = -1; -} +static void init_once_cb(void); static void *tls_get(void) { @@ -66,3 +93,22 @@ static int tls_set(void *p) #endif return !pthread_setspecific(tls_key.u.mt, p); } + +static void init_once_with_tls(void) +{ + tls_key.valid = !pthread_key_create(&tls_key.u.mt, free); + init_once_cb(); +} + +static int init_once(void) +{ + if (pthread_in_use) { + static pthread_once_t ctrl = PTHREAD_ONCE_INIT; + return !pthread_once(&ctrl, init_once_with_tls); + } else if (!tls_key_valid) { + tls_key.valid = -1; + init_once_cb(); + } + + return 1; +}