aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2018-11-08 14:28:22 +0100
committerAndreas Schwab <schwab@suse.de>2018-12-13 12:22:30 +0100
commitf21e8f8ca466320fed38bdb71526c574dae98026 (patch)
treeb4d30072a2ae6abdf42ed0e980d49e877894ec66 /nptl/pthread_rwlock_common.c
parentReindent nptl/pthread_rwlock_common.c (diff)
downloadglibc-f21e8f8ca466320fed38bdb71526c574dae98026.tar.gz
glibc-f21e8f8ca466320fed38bdb71526c574dae98026.tar.bz2
glibc-f21e8f8ca466320fed38bdb71526c574dae98026.zip
Fix rwlock stall with PREFER_WRITER_NONRECURSIVE_NP (bug 23861)
In the read lock function (__pthread_rwlock_rdlock_full) there was a code path which would fail to reload __readers while waiting for PTHREAD_RWLOCK_RWAITING to change. This failure to reload __readers into a local value meant that various conditionals used the old value of __readers and with only two threads left it could result in an indefinite stall of one of the readers (waiting for PTHREAD_RWLOCK_RWAITING to go to zero, but it never would).
Diffstat (limited to 'nptl/pthread_rwlock_common.c')
-rw-r--r--nptl/pthread_rwlock_common.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
index 5dd534271a..85fc1bcfc7 100644
--- a/nptl/pthread_rwlock_common.c
+++ b/nptl/pthread_rwlock_common.c
@@ -314,7 +314,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
harmless because the flag is just about the state of
__readers, and all threads set the flag under the same
conditions. */
- while ((atomic_load_relaxed (&rwlock->__data.__readers)
+ while (((r = atomic_load_relaxed (&rwlock->__data.__readers))
& PTHREAD_RWLOCK_RWAITING) != 0)
{
int private = __pthread_rwlock_get_private (rwlock);