diff options
Diffstat (limited to 'gl/glthread/lock.c')
| -rw-r--r-- | gl/glthread/lock.c | 112 |
1 files changed, 19 insertions, 93 deletions
diff --git a/gl/glthread/lock.c b/gl/glthread/lock.c index 6661ad6a..cfb9393c 100644 --- a/gl/glthread/lock.c +++ b/gl/glthread/lock.c | |||
| @@ -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-2026 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 |
| @@ -240,8 +240,6 @@ glthread_recursive_lock_destroy (gl_recursive_lock_t *lock) | |||
| 240 | return 0; | 240 | return 0; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 244 | |||
| 245 | #endif | 243 | #endif |
| 246 | 244 | ||
| 247 | /* ========================================================================= */ | 245 | /* ========================================================================= */ |
| @@ -257,21 +255,19 @@ glthread_recursive_lock_destroy (gl_recursive_lock_t *lock) | |||
| 257 | # if defined PTHREAD_RWLOCK_INITIALIZER || defined PTHREAD_RWLOCK_INITIALIZER_NP | 255 | # if defined PTHREAD_RWLOCK_INITIALIZER || defined PTHREAD_RWLOCK_INITIALIZER_NP |
| 258 | 256 | ||
| 259 | # if !HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER | 257 | # if !HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER |
| 260 | /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */ | 258 | /* glibc with bug https://sourceware.org/PR13701 */ |
| 261 | 259 | ||
| 262 | int | 260 | int |
| 263 | glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock) | 261 | glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock) |
| 264 | { | 262 | { |
| 265 | pthread_rwlockattr_t attributes; | 263 | pthread_rwlockattr_t attributes; |
| 266 | int err; | 264 | int err = pthread_rwlockattr_init (&attributes); |
| 267 | |||
| 268 | err = pthread_rwlockattr_init (&attributes); | ||
| 269 | if (err != 0) | 265 | if (err != 0) |
| 270 | return err; | 266 | return err; |
| 271 | /* Note: PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP is the only value that | 267 | /* Note: PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP is the only value that |
| 272 | causes the writer to be preferred. PTHREAD_RWLOCK_PREFER_WRITER_NP does not | 268 | causes the writer to be preferred. PTHREAD_RWLOCK_PREFER_WRITER_NP does not |
| 273 | do this; see | 269 | do this; see |
| 274 | http://man7.org/linux/man-pages/man3/pthread_rwlockattr_setkind_np.3.html */ | 270 | https://man7.org/linux/man-pages/man3/pthread_rwlockattr_setkind_np.3.html */ |
| 275 | err = pthread_rwlockattr_setkind_np (&attributes, | 271 | err = pthread_rwlockattr_setkind_np (&attributes, |
| 276 | PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); | 272 | PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); |
| 277 | if (err == 0) | 273 | if (err == 0) |
| @@ -288,9 +284,7 @@ glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock) | |||
| 288 | int | 284 | int |
| 289 | glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) | 285 | glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) |
| 290 | { | 286 | { |
| 291 | int err; | 287 | int err = pthread_rwlock_init (&lock->rwlock, NULL); |
| 292 | |||
| 293 | err = pthread_rwlock_init (&lock->rwlock, NULL); | ||
| 294 | if (err != 0) | 288 | if (err != 0) |
| 295 | return err; | 289 | return err; |
| 296 | lock->initialized = 1; | 290 | lock->initialized = 1; |
| @@ -302,9 +296,7 @@ glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock) | |||
| 302 | { | 296 | { |
| 303 | if (!lock->initialized) | 297 | if (!lock->initialized) |
| 304 | { | 298 | { |
| 305 | int err; | 299 | int err = pthread_mutex_lock (&lock->guard); |
| 306 | |||
| 307 | err = pthread_mutex_lock (&lock->guard); | ||
| 308 | if (err != 0) | 300 | if (err != 0) |
| 309 | return err; | 301 | return err; |
| 310 | if (!lock->initialized) | 302 | if (!lock->initialized) |
| @@ -328,9 +320,7 @@ glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock) | |||
| 328 | { | 320 | { |
| 329 | if (!lock->initialized) | 321 | if (!lock->initialized) |
| 330 | { | 322 | { |
| 331 | int err; | 323 | int err = pthread_mutex_lock (&lock->guard); |
| 332 | |||
| 333 | err = pthread_mutex_lock (&lock->guard); | ||
| 334 | if (err != 0) | 324 | if (err != 0) |
| 335 | return err; | 325 | return err; |
| 336 | if (!lock->initialized) | 326 | if (!lock->initialized) |
| @@ -360,11 +350,9 @@ glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock) | |||
| 360 | int | 350 | int |
| 361 | glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) | 351 | glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) |
| 362 | { | 352 | { |
| 363 | int err; | ||
| 364 | |||
| 365 | if (!lock->initialized) | 353 | if (!lock->initialized) |
| 366 | return EINVAL; | 354 | return EINVAL; |
| 367 | err = pthread_rwlock_destroy (&lock->rwlock); | 355 | int err = pthread_rwlock_destroy (&lock->rwlock); |
| 368 | if (err != 0) | 356 | if (err != 0) |
| 369 | return err; | 357 | return err; |
| 370 | lock->initialized = 0; | 358 | lock->initialized = 0; |
| @@ -378,9 +366,7 @@ glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) | |||
| 378 | int | 366 | int |
| 379 | glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) | 367 | glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) |
| 380 | { | 368 | { |
| 381 | int err; | 369 | int err = pthread_mutex_init (&lock->lock, NULL); |
| 382 | |||
| 383 | err = pthread_mutex_init (&lock->lock, NULL); | ||
| 384 | if (err != 0) | 370 | if (err != 0) |
| 385 | return err; | 371 | return err; |
| 386 | err = pthread_cond_init (&lock->waiting_readers, NULL); | 372 | err = pthread_cond_init (&lock->waiting_readers, NULL); |
| @@ -397,9 +383,7 @@ glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) | |||
| 397 | int | 383 | int |
| 398 | glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock) | 384 | glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock) |
| 399 | { | 385 | { |
| 400 | int err; | 386 | int err = pthread_mutex_lock (&lock->lock); |
| 401 | |||
| 402 | err = pthread_mutex_lock (&lock->lock); | ||
| 403 | if (err != 0) | 387 | if (err != 0) |
| 404 | return err; | 388 | return err; |
| 405 | /* Test whether only readers are currently running, and whether the runcount | 389 | /* Test whether only readers are currently running, and whether the runcount |
| @@ -424,9 +408,7 @@ glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock) | |||
| 424 | int | 408 | int |
| 425 | glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock) | 409 | glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock) |
| 426 | { | 410 | { |
| 427 | int err; | 411 | int err = pthread_mutex_lock (&lock->lock); |
| 428 | |||
| 429 | err = pthread_mutex_lock (&lock->lock); | ||
| 430 | if (err != 0) | 412 | if (err != 0) |
| 431 | return err; | 413 | return err; |
| 432 | /* Test whether no readers or writers are currently running. */ | 414 | /* Test whether no readers or writers are currently running. */ |
| @@ -451,9 +433,7 @@ glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock) | |||
| 451 | int | 433 | int |
| 452 | glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock) | 434 | glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock) |
| 453 | { | 435 | { |
| 454 | int err; | 436 | int err = pthread_mutex_lock (&lock->lock); |
| 455 | |||
| 456 | err = pthread_mutex_lock (&lock->lock); | ||
| 457 | if (err != 0) | 437 | if (err != 0) |
| 458 | return err; | 438 | return err; |
| 459 | if (lock->runcount < 0) | 439 | if (lock->runcount < 0) |
| @@ -507,9 +487,7 @@ glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock) | |||
| 507 | int | 487 | int |
| 508 | glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) | 488 | glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) |
| 509 | { | 489 | { |
| 510 | int err; | 490 | int err = pthread_mutex_destroy (&lock->lock); |
| 511 | |||
| 512 | err = pthread_mutex_destroy (&lock->lock); | ||
| 513 | if (err != 0) | 491 | if (err != 0) |
| 514 | return err; | 492 | return err; |
| 515 | err = pthread_cond_destroy (&lock->waiting_readers); | 493 | err = pthread_cond_destroy (&lock->waiting_readers); |
| @@ -533,9 +511,7 @@ int | |||
| 533 | glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) | 511 | glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) |
| 534 | { | 512 | { |
| 535 | pthread_mutexattr_t attributes; | 513 | pthread_mutexattr_t attributes; |
| 536 | int err; | 514 | int err = pthread_mutexattr_init (&attributes); |
| 537 | |||
| 538 | err = pthread_mutexattr_init (&attributes); | ||
| 539 | if (err != 0) | 515 | if (err != 0) |
| 540 | return err; | 516 | return err; |
| 541 | err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE); | 517 | err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE); |
| @@ -562,9 +538,7 @@ int | |||
| 562 | glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) | 538 | glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) |
| 563 | { | 539 | { |
| 564 | pthread_mutexattr_t attributes; | 540 | pthread_mutexattr_t attributes; |
| 565 | int err; | 541 | int err = pthread_mutexattr_init (&attributes); |
| 566 | |||
| 567 | err = pthread_mutexattr_init (&attributes); | ||
| 568 | if (err != 0) | 542 | if (err != 0) |
| 569 | return err; | 543 | return err; |
| 570 | err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE); | 544 | err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE); |
| @@ -591,9 +565,7 @@ glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock) | |||
| 591 | { | 565 | { |
| 592 | if (!lock->initialized) | 566 | if (!lock->initialized) |
| 593 | { | 567 | { |
| 594 | int err; | 568 | int err = pthread_mutex_lock (&lock->guard); |
| 595 | |||
| 596 | err = pthread_mutex_lock (&lock->guard); | ||
| 597 | if (err != 0) | 569 | if (err != 0) |
| 598 | return err; | 570 | return err; |
| 599 | if (!lock->initialized) | 571 | if (!lock->initialized) |
| @@ -623,11 +595,9 @@ glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock) | |||
| 623 | int | 595 | int |
| 624 | glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock) | 596 | glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock) |
| 625 | { | 597 | { |
| 626 | int err; | ||
| 627 | |||
| 628 | if (!lock->initialized) | 598 | if (!lock->initialized) |
| 629 | return EINVAL; | 599 | return EINVAL; |
| 630 | err = pthread_mutex_destroy (&lock->recmutex); | 600 | int err = pthread_mutex_destroy (&lock->recmutex); |
| 631 | if (err != 0) | 601 | if (err != 0) |
| 632 | return err; | 602 | return err; |
| 633 | lock->initialized = 0; | 603 | lock->initialized = 0; |
| @@ -641,9 +611,7 @@ glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock) | |||
| 641 | int | 611 | int |
| 642 | glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) | 612 | glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) |
| 643 | { | 613 | { |
| 644 | int err; | 614 | int err = pthread_mutex_init (&lock->mutex, NULL); |
| 645 | |||
| 646 | err = pthread_mutex_init (&lock->mutex, NULL); | ||
| 647 | if (err != 0) | 615 | if (err != 0) |
| 648 | return err; | 616 | return err; |
| 649 | lock->owner = (pthread_t) 0; | 617 | lock->owner = (pthread_t) 0; |
| @@ -657,9 +625,7 @@ glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock) | |||
| 657 | pthread_t self = pthread_self (); | 625 | pthread_t self = pthread_self (); |
| 658 | if (lock->owner != self) | 626 | if (lock->owner != self) |
| 659 | { | 627 | { |
| 660 | int err; | 628 | int err = pthread_mutex_lock (&lock->mutex); |
| 661 | |||
| 662 | err = pthread_mutex_lock (&lock->mutex); | ||
| 663 | if (err != 0) | 629 | if (err != 0) |
| 664 | return err; | 630 | return err; |
| 665 | lock->owner = self; | 631 | lock->owner = self; |
| @@ -698,46 +664,6 @@ glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock) | |||
| 698 | 664 | ||
| 699 | # endif | 665 | # endif |
| 700 | 666 | ||
| 701 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 702 | |||
| 703 | static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT; | ||
| 704 | |||
| 705 | int | ||
| 706 | glthread_once_singlethreaded (pthread_once_t *once_control) | ||
| 707 | { | ||
| 708 | /* We don't know whether pthread_once_t is an integer type, a floating-point | ||
| 709 | type, a pointer type, or a structure type. */ | ||
| 710 | char *firstbyte = (char *)once_control; | ||
| 711 | if (*firstbyte == *(const char *)&fresh_once) | ||
| 712 | { | ||
| 713 | /* First time use of once_control. Invert the first byte. */ | ||
| 714 | *firstbyte = ~ *(const char *)&fresh_once; | ||
| 715 | return 1; | ||
| 716 | } | ||
| 717 | else | ||
| 718 | return 0; | ||
| 719 | } | ||
| 720 | |||
| 721 | # if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) | ||
| 722 | |||
| 723 | int | ||
| 724 | glthread_once_multithreaded (pthread_once_t *once_control, | ||
| 725 | void (*init_function) (void)) | ||
| 726 | { | ||
| 727 | int err = pthread_once (once_control, init_function); | ||
| 728 | if (err == ENOSYS) | ||
| 729 | { | ||
| 730 | /* This happens on FreeBSD 11: The pthread_once function in libc returns | ||
| 731 | ENOSYS. */ | ||
| 732 | if (glthread_once_singlethreaded (once_control)) | ||
| 733 | init_function (); | ||
| 734 | return 0; | ||
| 735 | } | ||
| 736 | return err; | ||
| 737 | } | ||
| 738 | |||
| 739 | # endif | ||
| 740 | |||
| 741 | #endif | 667 | #endif |
| 742 | 668 | ||
| 743 | /* ========================================================================= */ | 669 | /* ========================================================================= */ |
