summaryrefslogtreecommitdiffstats
path: root/gl/glthread/lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/glthread/lock.c')
-rw-r--r--gl/glthread/lock.c112
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
262int 260int
263glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock) 261glthread_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)
288int 284int
289glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) 285glthread_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)
360int 350int
361glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) 351glthread_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)
378int 366int
379glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) 367glthread_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)
397int 383int
398glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock) 384glthread_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)
424int 408int
425glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock) 409glthread_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)
451int 433int
452glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock) 434glthread_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)
507int 487int
508glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) 488glthread_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
533glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) 511glthread_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
562glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) 538glthread_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)
623int 595int
624glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock) 596glthread_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)
641int 611int
642glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) 612glthread_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
703static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT;
704
705int
706glthread_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
723int
724glthread_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/* ========================================================================= */