diff options
Diffstat (limited to 'gl/glthread/lock.h')
| -rw-r--r-- | gl/glthread/lock.h | 161 |
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); | |||
| 187 | extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); | 180 | extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); |
| 188 | extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); | 181 | extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); |
| 189 | 182 | ||
| 190 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 191 | |||
| 192 | typedef 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; | |||
| 213 | extern "C" { | 198 | extern "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 () | ||
| 221 | extern 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 | |||
| 507 | typedef 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)) | ||
| 520 | extern int glthread_once_multithreaded (pthread_once_t *once_control, | ||
| 521 | void (*init_function) (void)); | ||
| 522 | # endif | ||
| 523 | extern 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 |
| 544 | extern "C" { | 435 | extern "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 | |||
| 616 | typedef 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 | |||
| 667 | typedef 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 */ |
