diff options
| author | Jörg Frings-Fürst <debian@jff.email> | 2024-10-20 15:21:58 +0200 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff.email> | 2024-10-20 15:21:58 +0200 | 
| commit | 630f99f29bd31a76d8d24da2975a045452c763ef (patch) | |
| tree | 0c801f68561bfb0930a4ade80d7ca3a7940887ab /lib/glthread | |
| parent | 84e26c587987e8484d55db4165f188b40c09e94b (diff) | |
| parent | 4682deeb62247d34de87f8e777f99e2d337fd377 (diff) | |
Update upstream source from tag 'upstream/1.3'
Update to upstream version '1.3'
with Debian dir 8a8e4828ddf646ece6c109b401e08d162be35936
Diffstat (limited to 'lib/glthread')
| -rw-r--r-- | lib/glthread/lock.c | 42 | ||||
| -rw-r--r-- | lib/glthread/lock.h | 151 | ||||
| -rw-r--r-- | lib/glthread/once.c | 80 | ||||
| -rw-r--r-- | lib/glthread/once.h | 272 | 
4 files changed, 356 insertions, 189 deletions
| diff --git a/lib/glthread/lock.c b/lib/glthread/lock.c index 6661ad6a..40b2a5ee 100644 --- a/lib/glthread/lock.c +++ b/lib/glthread/lock.c @@ -240,8 +240,6 @@ glthread_recursive_lock_destroy (gl_recursive_lock_t *lock)    return 0;  } -/* -------------------------- gl_once_t datatype -------------------------- */ -  #endif  /* ========================================================================= */ @@ -698,46 +696,6 @@ glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)  # endif -/* -------------------------- gl_once_t datatype -------------------------- */ - -static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT; - -int -glthread_once_singlethreaded (pthread_once_t *once_control) -{ -  /* We don't know whether pthread_once_t is an integer type, a floating-point -     type, a pointer type, or a structure type.  */ -  char *firstbyte = (char *)once_control; -  if (*firstbyte == *(const char *)&fresh_once) -    { -      /* First time use of once_control.  Invert the first byte.  */ -      *firstbyte = ~ *(const char *)&fresh_once; -      return 1; -    } -  else -    return 0; -} - -# if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) - -int -glthread_once_multithreaded (pthread_once_t *once_control, -                             void (*init_function) (void)) -{ -  int err = pthread_once (once_control, init_function); -  if (err == ENOSYS) -    { -      /* This happens on FreeBSD 11: The pthread_once function in libc returns -         ENOSYS.  */ -      if (glthread_once_singlethreaded (once_control)) -        init_function (); -      return 0; -    } -  return err; -} - -# endif -  #endif  /* ========================================================================= */ diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h index 2d5cb320..2b9c0f2e 100644 --- a/lib/glthread/lock.h +++ b/lib/glthread/lock.h @@ -64,13 +64,6 @@       Taking the lock:     err = glthread_recursive_lock_lock (&name);       Releasing the lock:  err = glthread_recursive_lock_unlock (&name);       De-initialization:   err = glthread_recursive_lock_destroy (&name); - -  Once-only execution: -     Type:                gl_once_t -     Initializer:         gl_once_define(extern, name) -     Execution:           gl_once (name, initfunction); -   Equivalent functions with control of error handling: -     Execution:           err = glthread_once (&name, initfunction);  */ @@ -88,17 +81,9 @@  #include <errno.h>  #include <stdlib.h> -#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 <threads.h> -#  pragma weak thrd_exit -#  define c11_threads_in_use() (thrd_exit != NULL) -# else -#  define c11_threads_in_use() 0 -# endif -#endif +#include "glthread/once.h" + +/* c11_threads_in_use() is defined in glthread/once.h.  */  /* ========================================================================= */ @@ -195,14 +180,6 @@ extern int glthread_recursive_lock_lock (gl_recursive_lock_t *lock);  extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);  extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); -/* -------------------------- gl_once_t datatype -------------------------- */ - -typedef once_flag gl_once_t; -# define gl_once_define(STORAGECLASS, NAME) \ -    STORAGECLASS once_flag NAME = ONCE_FLAG_INIT; -# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ -    (call_once (ONCE_CONTROL, INITFUNCTION), 0) -  # ifdef __cplusplus  }  # endif @@ -221,80 +198,7 @@ typedef once_flag gl_once_t;  extern "C" {  # endif -# if PTHREAD_IN_USE_DETECTION_HARD - -/* The pthread_in_use() detection needs to be done at runtime.  */ -#  define pthread_in_use() \ -     glthread_in_use () -extern int glthread_in_use (void); - -# endif - -# if USE_POSIX_THREADS_WEAK - -/* Use weak references to the POSIX threads library.  */ - -/* Weak references avoid dragging in external libraries if the other parts -   of the program don't use them.  Here we use them, because we don't want -   every program that uses libintl to depend on libpthread.  This assumes -   that libpthread would not be loaded after libintl; i.e. if libintl is -   loaded first, by an executable that does not depend on libpthread, and -   then a module is dynamically loaded that depends on libpthread, libintl -   will not be multithread-safe.  */ - -/* The way to test at runtime whether libpthread is present is to test -   whether a function pointer's value, such as &pthread_mutex_init, is -   non-NULL.  However, some versions of GCC have a bug through which, in -   PIC mode, &foo != NULL always evaluates to true if there is a direct -   call to foo(...) in the same function.  To avoid this, we test the -   address of a function in libpthread that we don't use.  */ - -#  pragma weak pthread_mutex_init -#  pragma weak pthread_mutex_lock -#  pragma weak pthread_mutex_unlock -#  pragma weak pthread_mutex_destroy -#  pragma weak pthread_rwlock_init -#  pragma weak pthread_rwlock_rdlock -#  pragma weak pthread_rwlock_wrlock -#  pragma weak pthread_rwlock_unlock -#  pragma weak pthread_rwlock_destroy -#  pragma weak pthread_once -#  pragma weak pthread_cond_init -#  pragma weak pthread_cond_wait -#  pragma weak pthread_cond_signal -#  pragma weak pthread_cond_broadcast -#  pragma weak pthread_cond_destroy -#  pragma weak pthread_mutexattr_init -#  pragma weak pthread_mutexattr_settype -#  pragma weak pthread_mutexattr_destroy -#  pragma weak pthread_rwlockattr_init -#  if __GNU_LIBRARY__ > 1 -#   pragma weak pthread_rwlockattr_setkind_np -#  endif -#  pragma weak pthread_rwlockattr_destroy -#  ifndef pthread_self -#   pragma weak pthread_self -#  endif - -#  if !PTHREAD_IN_USE_DETECTION_HARD -    /* Considering all platforms with USE_POSIX_THREADS_WEAK, only few symbols -       can be used to determine whether libpthread is in use.  These are: -         pthread_mutexattr_gettype -         pthread_rwlockattr_destroy -         pthread_rwlockattr_init -     */ -#   pragma weak pthread_mutexattr_gettype -#   define pthread_in_use() \ -      (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) -#  endif - -# else - -#  if !PTHREAD_IN_USE_DETECTION_HARD -#   define pthread_in_use() 1 -#  endif - -# endif +/* pthread_in_use() is defined in glthread/once.h.  */  /* -------------------------- gl_lock_t datatype -------------------------- */ @@ -510,26 +414,6 @@ extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *l  # endif -/* -------------------------- gl_once_t datatype -------------------------- */ - -typedef pthread_once_t gl_once_t; -# define gl_once_define(STORAGECLASS, NAME) \ -    STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; -# if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK -#  define glthread_once(ONCE_CONTROL, INITFUNCTION) \ -     (pthread_in_use ()                                                        \ -      ? pthread_once (ONCE_CONTROL, INITFUNCTION)                              \ -      : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) -# else -#  define glthread_once(ONCE_CONTROL, INITFUNCTION) \ -     (pthread_in_use ()                                                        \ -      ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)               \ -      : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) -extern int glthread_once_multithreaded (pthread_once_t *once_control, -                                        void (*init_function) (void)); -# endif -extern int glthread_once_singlethreaded (pthread_once_t *once_control); -  # ifdef __cplusplus  }  # endif @@ -546,7 +430,6 @@ extern int glthread_once_singlethreaded (pthread_once_t *once_control);  # include "windows-mutex.h"  # include "windows-rwlock.h"  # include "windows-recmutex.h" -# include "windows-once.h"  # ifdef __cplusplus  extern "C" { @@ -619,14 +502,6 @@ typedef glwthread_recmutex_t gl_recursive_lock_t;  # define glthread_recursive_lock_destroy(LOCK) \      glwthread_recmutex_destroy (LOCK) -/* -------------------------- gl_once_t datatype -------------------------- */ - -typedef glwthread_once_t gl_once_t; -# define gl_once_define(STORAGECLASS, NAME) \ -    STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT; -# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ -    (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0) -  # ifdef __cplusplus  }  # endif @@ -670,14 +545,6 @@ typedef int gl_recursive_lock_t;  # define glthread_recursive_lock_unlock(NAME) 0  # define glthread_recursive_lock_destroy(NAME) 0 -/* -------------------------- gl_once_t datatype -------------------------- */ - -typedef int gl_once_t; -# define gl_once_define(STORAGECLASS, NAME) \ -    STORAGECLASS gl_once_t NAME = 0; -# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ -    (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0) -  #endif  /* ========================================================================= */ @@ -784,16 +651,6 @@ typedef int gl_once_t;       }                                              \     while (0) -/* -------------------------- gl_once_t datatype -------------------------- */ - -#define gl_once(NAME, INITFUNCTION) \ -   do                                           \ -     {                                          \ -       if (glthread_once (&NAME, INITFUNCTION)) \ -         abort ();                              \ -     }                                          \ -   while (0) -  /* ========================================================================= */  #endif /* _LOCK_H */ diff --git a/lib/glthread/once.c b/lib/glthread/once.c new file mode 100644 index 00000000..869ba3ba --- /dev/null +++ b/lib/glthread/once.c @@ -0,0 +1,80 @@ +/* Once-only initialization in multithreaded situations. +   Copyright (C) 2005-2024 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 file 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 +   GNU Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public License +   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2005. +   Based on GCC's gthr-posix.h, gthr-posix95.h.  */ + +#include <config.h> + +#include "glthread/once.h" + +/* ========================================================================= */ + +#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS + +#endif + +/* ========================================================================= */ + +#if USE_POSIX_THREADS + +static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT; + +int +glthread_once_singlethreaded (pthread_once_t *once_control) +{ +  /* We don't know whether pthread_once_t is an integer type, a floating-point +     type, a pointer type, or a structure type.  */ +  char *firstbyte = (char *)once_control; +  if (*firstbyte == *(const char *)&fresh_once) +    { +      /* First time use of once_control.  Invert the first byte.  */ +      *firstbyte = ~ *(const char *)&fresh_once; +      return 1; +    } +  else +    return 0; +} + +# if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) + +int +glthread_once_multithreaded (pthread_once_t *once_control, +                             void (*init_function) (void)) +{ +  int err = pthread_once (once_control, init_function); +  if (err == ENOSYS) +    { +      /* This happens on FreeBSD 11: The pthread_once function in libc returns +         ENOSYS.  */ +      if (glthread_once_singlethreaded (once_control)) +        init_function (); +      return 0; +    } +  return err; +} + +# endif + +#endif + +/* ========================================================================= */ + +#if USE_WINDOWS_THREADS + +#endif + +/* ========================================================================= */ diff --git a/lib/glthread/once.h b/lib/glthread/once.h new file mode 100644 index 00000000..2452f88d --- /dev/null +++ b/lib/glthread/once.h @@ -0,0 +1,272 @@ +/* Once-only initialization in multithreaded situations. +   Copyright (C) 2005-2024 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 file 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 +   GNU Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public License +   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2005. +   Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h.  */ + +/* This file contains once-only initialization primitives for use with a given +   thread library. +   It does not contain primitives for creating threads or for other +   synchronization primitives. + +  Once-only execution: +     Type:                gl_once_t +     Initializer:         gl_once_define(extern, name) +     Execution:           gl_once (name, initfunction); +   Equivalent functions with control of error handling: +     Execution:           err = glthread_once (&name, initfunction); +*/ + + +#ifndef _ONCE_H +#define _ONCE_H + +/* This file uses HAVE_THREADS_H.  */ +#if !_GL_CONFIG_H_INCLUDED + #error "Please include config.h first." +#endif + +#include <errno.h> +#include <stdlib.h> + +#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 <threads.h> +#  pragma weak thrd_exit +#  define c11_threads_in_use() (thrd_exit != NULL) +# else +#  define c11_threads_in_use() 0 +# endif +#endif + +/* ========================================================================= */ + +#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS + +/* Use the ISO C threads library.  */ + +# include <threads.h> + +# ifdef __cplusplus +extern "C" { +# endif + +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef once_flag gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ +    STORAGECLASS once_flag NAME = ONCE_FLAG_INIT; +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ +    (call_once (ONCE_CONTROL, INITFUNCTION), 0) + +# ifdef __cplusplus +} +# endif + +#endif + +/* ========================================================================= */ + +#if USE_POSIX_THREADS + +/* Use the POSIX threads library.  */ + +# include <pthread.h> + +# ifdef __cplusplus +extern "C" { +# endif + +# if PTHREAD_IN_USE_DETECTION_HARD + +/* The pthread_in_use() detection needs to be done at runtime.  */ +#  define pthread_in_use() \ +     glthread_in_use () +extern int glthread_in_use (void); + +# endif + +# if USE_POSIX_THREADS_WEAK + +/* Use weak references to the POSIX threads library.  */ + +/* Weak references avoid dragging in external libraries if the other parts +   of the program don't use them.  Here we use them, because we don't want +   every program that uses libintl to depend on libpthread.  This assumes +   that libpthread would not be loaded after libintl; i.e. if libintl is +   loaded first, by an executable that does not depend on libpthread, and +   then a module is dynamically loaded that depends on libpthread, libintl +   will not be multithread-safe.  */ + +/* The way to test at runtime whether libpthread is present is to test +   whether a function pointer's value, such as &pthread_mutex_init, is +   non-NULL.  However, some versions of GCC have a bug through which, in +   PIC mode, &foo != NULL always evaluates to true if there is a direct +   call to foo(...) in the same function.  To avoid this, we test the +   address of a function in libpthread that we don't use.  */ + +#  pragma weak pthread_mutex_init +#  pragma weak pthread_mutex_lock +#  pragma weak pthread_mutex_unlock +#  pragma weak pthread_mutex_destroy +/* Work around clang bug <https://github.com/llvm/llvm-project/issues/104670> */ +#  ifndef pthread_rwlock_init +#   pragma weak pthread_rwlock_init +#  endif +#  pragma weak pthread_rwlock_rdlock +#  pragma weak pthread_rwlock_wrlock +#  pragma weak pthread_rwlock_unlock +#  pragma weak pthread_rwlock_destroy +#  pragma weak pthread_once +#  pragma weak pthread_cond_init +#  pragma weak pthread_cond_wait +#  pragma weak pthread_cond_signal +#  pragma weak pthread_cond_broadcast +#  pragma weak pthread_cond_destroy +#  pragma weak pthread_mutexattr_init +#  pragma weak pthread_mutexattr_settype +#  pragma weak pthread_mutexattr_destroy +/* Work around clang bug <https://github.com/llvm/llvm-project/issues/104670> */ +#  ifndef pthread_rwlockattr_init +#   pragma weak pthread_rwlockattr_init +#  endif +#  if __GNU_LIBRARY__ > 1 +#   pragma weak pthread_rwlockattr_setkind_np +#  endif +#  pragma weak pthread_rwlockattr_destroy +#  ifndef pthread_self +#   pragma weak pthread_self +#  endif + +#  if !PTHREAD_IN_USE_DETECTION_HARD +    /* Considering all platforms with USE_POSIX_THREADS_WEAK, only few symbols +       can be used to determine whether libpthread is in use.  These are: +         pthread_mutexattr_gettype +         pthread_rwlockattr_destroy +         pthread_rwlockattr_init +     */ +#   pragma weak pthread_mutexattr_gettype +#   define pthread_in_use() \ +      (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) +#  endif + +# else + +#  if !PTHREAD_IN_USE_DETECTION_HARD +#   define pthread_in_use() 1 +#  endif + +# endif + +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef pthread_once_t gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ +    STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; +# if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK +#  define glthread_once(ONCE_CONTROL, INITFUNCTION) \ +     (pthread_in_use ()                                                        \ +      ? pthread_once (ONCE_CONTROL, INITFUNCTION)                              \ +      : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) +# else +#  define glthread_once(ONCE_CONTROL, INITFUNCTION) \ +     (pthread_in_use ()                                                        \ +      ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)               \ +      : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) +extern int glthread_once_multithreaded (pthread_once_t *once_control, +                                        void (*init_function) (void)); +# endif +extern int glthread_once_singlethreaded (pthread_once_t *once_control); + +# ifdef __cplusplus +} +# endif + +#endif + +/* ========================================================================= */ + +#if USE_WINDOWS_THREADS + +# define WIN32_LEAN_AND_MEAN  /* avoid including junk */ +# include <windows.h> + +# include "windows-once.h" + +# ifdef __cplusplus +extern "C" { +# endif + +/* We can use CRITICAL_SECTION directly, rather than the native Windows Event, +   Mutex, Semaphore types, because +     - we need only to synchronize inside a single process (address space), +       not inter-process locking, +     - we don't need to support trylock operations.  (TryEnterCriticalSection +       does not work on Windows 95/98/ME.  Packages that need trylock usually +       define their own mutex type.)  */ + +/* There is no way to statically initialize a CRITICAL_SECTION.  It needs +   to be done lazily, once only.  For this we need spinlocks.  */ + +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef glwthread_once_t gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ +    STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT; +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ +    (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0) + +# ifdef __cplusplus +} +# endif + +#endif + +/* ========================================================================= */ + +#if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS) + +/* Provide dummy implementation if threads are not supported.  */ + +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef int gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ +    STORAGECLASS gl_once_t NAME = 0; +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ +    (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0) + +#endif + +/* ========================================================================= */ + +/* Macros with built-in error handling.  */ + +/* -------------------------- gl_once_t datatype -------------------------- */ + +#define gl_once(NAME, INITFUNCTION) \ +   do                                           \ +     {                                          \ +       if (glthread_once (&NAME, INITFUNCTION)) \ +         abort ();                              \ +     }                                          \ +   while (0) + +/* ========================================================================= */ + +#endif /* _ONCE_H */ | 
