summaryrefslogtreecommitdiffstats
path: root/gl/glthread/lock.h
diff options
context:
space:
mode:
Diffstat (limited to 'gl/glthread/lock.h')
-rw-r--r--gl/glthread/lock.h161
1 files changed, 13 insertions, 148 deletions
diff --git a/gl/glthread/lock.h b/gl/glthread/lock.h
index ae3ee2d6..d6ccc202 100644
--- a/gl/glthread/lock.h
+++ b/gl/glthread/lock.h
@@ -1,5 +1,5 @@
1/* Locking in multithreaded situations. 1/* Locking in multithreaded situations.
2 Copyright (C) 2005-2023 Free Software Foundation, Inc. 2 Copyright (C) 2005-2025 Free Software Foundation, Inc.
3 3
4 This file is free software: you can redistribute it and/or modify 4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as 5 it under the terms of the GNU Lesser General Public License as
@@ -64,33 +64,26 @@
64 Taking the lock: err = glthread_recursive_lock_lock (&name); 64 Taking the lock: err = glthread_recursive_lock_lock (&name);
65 Releasing the lock: err = glthread_recursive_lock_unlock (&name); 65 Releasing the lock: err = glthread_recursive_lock_unlock (&name);
66 De-initialization: err = glthread_recursive_lock_destroy (&name); 66 De-initialization: err = glthread_recursive_lock_destroy (&name);
67
68 Once-only execution:
69 Type: gl_once_t
70 Initializer: gl_once_define(extern, name)
71 Execution: gl_once (name, initfunction);
72 Equivalent functions with control of error handling:
73 Execution: err = glthread_once (&name, initfunction);
74*/ 67*/
75 68
76 69
77#ifndef _LOCK_H 70#ifndef _LOCK_H
78#define _LOCK_H 71#define _LOCK_H
79 72
73/* This file uses HAVE_THREADS_H, HAVE_PTHREAD_RWLOCK,
74 HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER,
75 PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
76 HAVE_PTHREAD_MUTEX_RECURSIVE. */
77#if !_GL_CONFIG_H_INCLUDED
78 #error "Please include config.h first."
79#endif
80
80#include <errno.h> 81#include <errno.h>
81#include <stdlib.h> 82#include <stdlib.h>
82 83
83#if !defined c11_threads_in_use 84#include "glthread/once.h"
84# if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC 85
85# define c11_threads_in_use() 1 86/* c11_threads_in_use() is defined in glthread/once.h. */
86# elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK
87# include <threads.h>
88# pragma weak thrd_exit
89# define c11_threads_in_use() (thrd_exit != NULL)
90# else
91# define c11_threads_in_use() 0
92# endif
93#endif
94 87
95/* ========================================================================= */ 88/* ========================================================================= */
96 89
@@ -187,14 +180,6 @@ extern int glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
187extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); 180extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
188extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); 181extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
189 182
190/* -------------------------- gl_once_t datatype -------------------------- */
191
192typedef once_flag gl_once_t;
193# define gl_once_define(STORAGECLASS, NAME) \
194 STORAGECLASS once_flag NAME = ONCE_FLAG_INIT;
195# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
196 (call_once (ONCE_CONTROL, INITFUNCTION), 0)
197
198# ifdef __cplusplus 183# ifdef __cplusplus
199} 184}
200# endif 185# endif
@@ -213,80 +198,7 @@ typedef once_flag gl_once_t;
213extern "C" { 198extern "C" {
214# endif 199# endif
215 200
216# if PTHREAD_IN_USE_DETECTION_HARD 201/* pthread_in_use() is defined in glthread/once.h. */
217
218/* The pthread_in_use() detection needs to be done at runtime. */
219# define pthread_in_use() \
220 glthread_in_use ()
221extern int glthread_in_use (void);
222
223# endif
224
225# if USE_POSIX_THREADS_WEAK
226
227/* Use weak references to the POSIX threads library. */
228
229/* Weak references avoid dragging in external libraries if the other parts
230 of the program don't use them. Here we use them, because we don't want
231 every program that uses libintl to depend on libpthread. This assumes
232 that libpthread would not be loaded after libintl; i.e. if libintl is
233 loaded first, by an executable that does not depend on libpthread, and
234 then a module is dynamically loaded that depends on libpthread, libintl
235 will not be multithread-safe. */
236
237/* The way to test at runtime whether libpthread is present is to test
238 whether a function pointer's value, such as &pthread_mutex_init, is
239 non-NULL. However, some versions of GCC have a bug through which, in
240 PIC mode, &foo != NULL always evaluates to true if there is a direct
241 call to foo(...) in the same function. To avoid this, we test the
242 address of a function in libpthread that we don't use. */
243
244# pragma weak pthread_mutex_init
245# pragma weak pthread_mutex_lock
246# pragma weak pthread_mutex_unlock
247# pragma weak pthread_mutex_destroy
248# pragma weak pthread_rwlock_init
249# pragma weak pthread_rwlock_rdlock
250# pragma weak pthread_rwlock_wrlock
251# pragma weak pthread_rwlock_unlock
252# pragma weak pthread_rwlock_destroy
253# pragma weak pthread_once
254# pragma weak pthread_cond_init
255# pragma weak pthread_cond_wait
256# pragma weak pthread_cond_signal
257# pragma weak pthread_cond_broadcast
258# pragma weak pthread_cond_destroy
259# pragma weak pthread_mutexattr_init
260# pragma weak pthread_mutexattr_settype
261# pragma weak pthread_mutexattr_destroy
262# pragma weak pthread_rwlockattr_init
263# if __GNU_LIBRARY__ > 1
264# pragma weak pthread_rwlockattr_setkind_np
265# endif
266# pragma weak pthread_rwlockattr_destroy
267# ifndef pthread_self
268# pragma weak pthread_self
269# endif
270
271# if !PTHREAD_IN_USE_DETECTION_HARD
272 /* Considering all platforms with USE_POSIX_THREADS_WEAK, only few symbols
273 can be used to determine whether libpthread is in use. These are:
274 pthread_mutexattr_gettype
275 pthread_rwlockattr_destroy
276 pthread_rwlockattr_init
277 */
278# pragma weak pthread_mutexattr_gettype
279# define pthread_in_use() \
280 (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
281# endif
282
283# else
284
285# if !PTHREAD_IN_USE_DETECTION_HARD
286# define pthread_in_use() 1
287# endif
288
289# endif
290 202
291/* -------------------------- gl_lock_t datatype -------------------------- */ 203/* -------------------------- gl_lock_t datatype -------------------------- */
292 204
@@ -502,26 +414,6 @@ extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *l
502 414
503# endif 415# endif
504 416
505/* -------------------------- gl_once_t datatype -------------------------- */
506
507typedef pthread_once_t gl_once_t;
508# define gl_once_define(STORAGECLASS, NAME) \
509 STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
510# if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK
511# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
512 (pthread_in_use () \
513 ? pthread_once (ONCE_CONTROL, INITFUNCTION) \
514 : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
515# else
516# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
517 (pthread_in_use () \
518 ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \
519 : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
520extern int glthread_once_multithreaded (pthread_once_t *once_control,
521 void (*init_function) (void));
522# endif
523extern int glthread_once_singlethreaded (pthread_once_t *once_control);
524
525# ifdef __cplusplus 417# ifdef __cplusplus
526} 418}
527# endif 419# endif
@@ -538,7 +430,6 @@ extern int glthread_once_singlethreaded (pthread_once_t *once_control);
538# include "windows-mutex.h" 430# include "windows-mutex.h"
539# include "windows-rwlock.h" 431# include "windows-rwlock.h"
540# include "windows-recmutex.h" 432# include "windows-recmutex.h"
541# include "windows-once.h"
542 433
543# ifdef __cplusplus 434# ifdef __cplusplus
544extern "C" { 435extern "C" {
@@ -611,14 +502,6 @@ typedef glwthread_recmutex_t gl_recursive_lock_t;
611# define glthread_recursive_lock_destroy(LOCK) \ 502# define glthread_recursive_lock_destroy(LOCK) \
612 glwthread_recmutex_destroy (LOCK) 503 glwthread_recmutex_destroy (LOCK)
613 504
614/* -------------------------- gl_once_t datatype -------------------------- */
615
616typedef glwthread_once_t gl_once_t;
617# define gl_once_define(STORAGECLASS, NAME) \
618 STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT;
619# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
620 (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0)
621
622# ifdef __cplusplus 505# ifdef __cplusplus
623} 506}
624# endif 507# endif
@@ -662,14 +545,6 @@ typedef int gl_recursive_lock_t;
662# define glthread_recursive_lock_unlock(NAME) 0 545# define glthread_recursive_lock_unlock(NAME) 0
663# define glthread_recursive_lock_destroy(NAME) 0 546# define glthread_recursive_lock_destroy(NAME) 0
664 547
665/* -------------------------- gl_once_t datatype -------------------------- */
666
667typedef int gl_once_t;
668# define gl_once_define(STORAGECLASS, NAME) \
669 STORAGECLASS gl_once_t NAME = 0;
670# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
671 (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0)
672
673#endif 548#endif
674 549
675/* ========================================================================= */ 550/* ========================================================================= */
@@ -776,16 +651,6 @@ typedef int gl_once_t;
776 } \ 651 } \
777 while (0) 652 while (0)
778 653
779/* -------------------------- gl_once_t datatype -------------------------- */
780
781#define gl_once(NAME, INITFUNCTION) \
782 do \
783 { \
784 if (glthread_once (&NAME, INITFUNCTION)) \
785 abort (); \
786 } \
787 while (0)
788
789/* ========================================================================= */ 654/* ========================================================================= */
790 655
791#endif /* _LOCK_H */ 656#endif /* _LOCK_H */