diff options
Diffstat (limited to 'gl/glthread/lock.h')
| -rw-r--r-- | gl/glthread/lock.h | 153 |
1 files changed, 5 insertions, 148 deletions
diff --git a/gl/glthread/lock.h b/gl/glthread/lock.h index 2d5cb320..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-2024 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,13 +64,6 @@ | |||
| 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 | ||
| @@ -88,17 +81,9 @@ | |||
| 88 | #include <errno.h> | 81 | #include <errno.h> |
| 89 | #include <stdlib.h> | 82 | #include <stdlib.h> |
| 90 | 83 | ||
| 91 | #if !defined c11_threads_in_use | 84 | #include "glthread/once.h" |
| 92 | # if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC | 85 | |
| 93 | # define c11_threads_in_use() 1 | 86 | /* c11_threads_in_use() is defined in glthread/once.h. */ |
| 94 | # elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK | ||
| 95 | # include <threads.h> | ||
| 96 | # pragma weak thrd_exit | ||
| 97 | # define c11_threads_in_use() (thrd_exit != NULL) | ||
| 98 | # else | ||
| 99 | # define c11_threads_in_use() 0 | ||
| 100 | # endif | ||
| 101 | #endif | ||
| 102 | 87 | ||
| 103 | /* ========================================================================= */ | 88 | /* ========================================================================= */ |
| 104 | 89 | ||
| @@ -195,14 +180,6 @@ extern int glthread_recursive_lock_lock (gl_recursive_lock_t *lock); | |||
| 195 | extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); | 180 | extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); |
| 196 | extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); | 181 | extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); |
| 197 | 182 | ||
| 198 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 199 | |||
| 200 | typedef once_flag gl_once_t; | ||
| 201 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 202 | STORAGECLASS once_flag NAME = ONCE_FLAG_INIT; | ||
| 203 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 204 | (call_once (ONCE_CONTROL, INITFUNCTION), 0) | ||
| 205 | |||
| 206 | # ifdef __cplusplus | 183 | # ifdef __cplusplus |
| 207 | } | 184 | } |
| 208 | # endif | 185 | # endif |
| @@ -221,80 +198,7 @@ typedef once_flag gl_once_t; | |||
| 221 | extern "C" { | 198 | extern "C" { |
| 222 | # endif | 199 | # endif |
| 223 | 200 | ||
| 224 | # if PTHREAD_IN_USE_DETECTION_HARD | 201 | /* pthread_in_use() is defined in glthread/once.h. */ |
| 225 | |||
| 226 | /* The pthread_in_use() detection needs to be done at runtime. */ | ||
| 227 | # define pthread_in_use() \ | ||
| 228 | glthread_in_use () | ||
| 229 | extern int glthread_in_use (void); | ||
| 230 | |||
| 231 | # endif | ||
| 232 | |||
| 233 | # if USE_POSIX_THREADS_WEAK | ||
| 234 | |||
| 235 | /* Use weak references to the POSIX threads library. */ | ||
| 236 | |||
| 237 | /* Weak references avoid dragging in external libraries if the other parts | ||
| 238 | of the program don't use them. Here we use them, because we don't want | ||
| 239 | every program that uses libintl to depend on libpthread. This assumes | ||
| 240 | that libpthread would not be loaded after libintl; i.e. if libintl is | ||
| 241 | loaded first, by an executable that does not depend on libpthread, and | ||
| 242 | then a module is dynamically loaded that depends on libpthread, libintl | ||
| 243 | will not be multithread-safe. */ | ||
| 244 | |||
| 245 | /* The way to test at runtime whether libpthread is present is to test | ||
| 246 | whether a function pointer's value, such as &pthread_mutex_init, is | ||
| 247 | non-NULL. However, some versions of GCC have a bug through which, in | ||
| 248 | PIC mode, &foo != NULL always evaluates to true if there is a direct | ||
| 249 | call to foo(...) in the same function. To avoid this, we test the | ||
| 250 | address of a function in libpthread that we don't use. */ | ||
| 251 | |||
| 252 | # pragma weak pthread_mutex_init | ||
| 253 | # pragma weak pthread_mutex_lock | ||
| 254 | # pragma weak pthread_mutex_unlock | ||
| 255 | # pragma weak pthread_mutex_destroy | ||
| 256 | # pragma weak pthread_rwlock_init | ||
| 257 | # pragma weak pthread_rwlock_rdlock | ||
| 258 | # pragma weak pthread_rwlock_wrlock | ||
| 259 | # pragma weak pthread_rwlock_unlock | ||
| 260 | # pragma weak pthread_rwlock_destroy | ||
| 261 | # pragma weak pthread_once | ||
| 262 | # pragma weak pthread_cond_init | ||
| 263 | # pragma weak pthread_cond_wait | ||
| 264 | # pragma weak pthread_cond_signal | ||
| 265 | # pragma weak pthread_cond_broadcast | ||
| 266 | # pragma weak pthread_cond_destroy | ||
| 267 | # pragma weak pthread_mutexattr_init | ||
| 268 | # pragma weak pthread_mutexattr_settype | ||
| 269 | # pragma weak pthread_mutexattr_destroy | ||
| 270 | # pragma weak pthread_rwlockattr_init | ||
| 271 | # if __GNU_LIBRARY__ > 1 | ||
| 272 | # pragma weak pthread_rwlockattr_setkind_np | ||
| 273 | # endif | ||
| 274 | # pragma weak pthread_rwlockattr_destroy | ||
| 275 | # ifndef pthread_self | ||
| 276 | # pragma weak pthread_self | ||
| 277 | # endif | ||
| 278 | |||
| 279 | # if !PTHREAD_IN_USE_DETECTION_HARD | ||
| 280 | /* Considering all platforms with USE_POSIX_THREADS_WEAK, only few symbols | ||
| 281 | can be used to determine whether libpthread is in use. These are: | ||
| 282 | pthread_mutexattr_gettype | ||
| 283 | pthread_rwlockattr_destroy | ||
| 284 | pthread_rwlockattr_init | ||
| 285 | */ | ||
| 286 | # pragma weak pthread_mutexattr_gettype | ||
| 287 | # define pthread_in_use() \ | ||
| 288 | (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) | ||
| 289 | # endif | ||
| 290 | |||
| 291 | # else | ||
| 292 | |||
| 293 | # if !PTHREAD_IN_USE_DETECTION_HARD | ||
| 294 | # define pthread_in_use() 1 | ||
| 295 | # endif | ||
| 296 | |||
| 297 | # endif | ||
| 298 | 202 | ||
| 299 | /* -------------------------- gl_lock_t datatype -------------------------- */ | 203 | /* -------------------------- gl_lock_t datatype -------------------------- */ |
| 300 | 204 | ||
| @@ -510,26 +414,6 @@ extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *l | |||
| 510 | 414 | ||
| 511 | # endif | 415 | # endif |
| 512 | 416 | ||
| 513 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 514 | |||
| 515 | typedef pthread_once_t gl_once_t; | ||
| 516 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 517 | STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; | ||
| 518 | # if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK | ||
| 519 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 520 | (pthread_in_use () \ | ||
| 521 | ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ | ||
| 522 | : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) | ||
| 523 | # else | ||
| 524 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 525 | (pthread_in_use () \ | ||
| 526 | ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ | ||
| 527 | : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) | ||
| 528 | extern int glthread_once_multithreaded (pthread_once_t *once_control, | ||
| 529 | void (*init_function) (void)); | ||
| 530 | # endif | ||
| 531 | extern int glthread_once_singlethreaded (pthread_once_t *once_control); | ||
| 532 | |||
| 533 | # ifdef __cplusplus | 417 | # ifdef __cplusplus |
| 534 | } | 418 | } |
| 535 | # endif | 419 | # endif |
| @@ -546,7 +430,6 @@ extern int glthread_once_singlethreaded (pthread_once_t *once_control); | |||
| 546 | # include "windows-mutex.h" | 430 | # include "windows-mutex.h" |
| 547 | # include "windows-rwlock.h" | 431 | # include "windows-rwlock.h" |
| 548 | # include "windows-recmutex.h" | 432 | # include "windows-recmutex.h" |
| 549 | # include "windows-once.h" | ||
| 550 | 433 | ||
| 551 | # ifdef __cplusplus | 434 | # ifdef __cplusplus |
| 552 | extern "C" { | 435 | extern "C" { |
| @@ -619,14 +502,6 @@ typedef glwthread_recmutex_t gl_recursive_lock_t; | |||
| 619 | # define glthread_recursive_lock_destroy(LOCK) \ | 502 | # define glthread_recursive_lock_destroy(LOCK) \ |
| 620 | glwthread_recmutex_destroy (LOCK) | 503 | glwthread_recmutex_destroy (LOCK) |
| 621 | 504 | ||
| 622 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 623 | |||
| 624 | typedef glwthread_once_t gl_once_t; | ||
| 625 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 626 | STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT; | ||
| 627 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 628 | (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0) | ||
| 629 | |||
| 630 | # ifdef __cplusplus | 505 | # ifdef __cplusplus |
| 631 | } | 506 | } |
| 632 | # endif | 507 | # endif |
| @@ -670,14 +545,6 @@ typedef int gl_recursive_lock_t; | |||
| 670 | # define glthread_recursive_lock_unlock(NAME) 0 | 545 | # define glthread_recursive_lock_unlock(NAME) 0 |
| 671 | # define glthread_recursive_lock_destroy(NAME) 0 | 546 | # define glthread_recursive_lock_destroy(NAME) 0 |
| 672 | 547 | ||
| 673 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 674 | |||
| 675 | typedef int gl_once_t; | ||
| 676 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 677 | STORAGECLASS gl_once_t NAME = 0; | ||
| 678 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 679 | (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0) | ||
| 680 | |||
| 681 | #endif | 548 | #endif |
| 682 | 549 | ||
| 683 | /* ========================================================================= */ | 550 | /* ========================================================================= */ |
| @@ -784,16 +651,6 @@ typedef int gl_once_t; | |||
| 784 | } \ | 651 | } \ |
| 785 | while (0) | 652 | while (0) |
| 786 | 653 | ||
| 787 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 788 | |||
| 789 | #define gl_once(NAME, INITFUNCTION) \ | ||
| 790 | do \ | ||
| 791 | { \ | ||
| 792 | if (glthread_once (&NAME, INITFUNCTION)) \ | ||
| 793 | abort (); \ | ||
| 794 | } \ | ||
| 795 | while (0) | ||
| 796 | |||
| 797 | /* ========================================================================= */ | 654 | /* ========================================================================= */ |
| 798 | 655 | ||
| 799 | #endif /* _LOCK_H */ | 656 | #endif /* _LOCK_H */ |
