summaryrefslogtreecommitdiff
path: root/nptl/pthread_rwlock_timedwrlock.c
diff options
context:
space:
mode:
authorTorvald Riegel <triegel@redhat.com>2015-04-28 23:24:36 +0200
committerTorvald Riegel <triegel@redhat.com>2015-06-04 15:34:30 +0200
commitb634486d57a14b53f1cfcf739e41ddf826e51977 (patch)
tree65ad6788da14adc8effdd9d1b4236ac24af710d7 /nptl/pthread_rwlock_timedwrlock.c
parent3c9c61febede148b79d8509e16588152d99b3774 (diff)
Fix missing wake-ups in pthread_rwlock_rdlock.
This adds wake-ups that would be missing if assuming that for a non-writer-preferring rwlock, if one thread has acquired a rdlock and does not release it, another thread will eventually acquire a rdlock too despite concurrent write lock acquisition attempts. BZ 14958 is about supporting this assumption. Strictly speaking, this isn't a valid test case, but nonetheless worth supporting (see comment 7 of BZ 14958).
Diffstat (limited to 'nptl/pthread_rwlock_timedwrlock.c')
-rw-r--r--nptl/pthread_rwlock_timedwrlock.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c
index a759fa997f..c54253450b 100644
--- a/nptl/pthread_rwlock_timedwrlock.c
+++ b/nptl/pthread_rwlock_timedwrlock.c
@@ -141,8 +141,16 @@ pthread_rwlock_timedwrlock (rwlock, abstime)
/* If we prefer writers, it can have happened that readers blocked
for us to acquire the lock first. If we have timed out, we need
to wake such readers if there are any, and if there is no writer
- currently (otherwise, the writer will take care of wake-up). */
- if (!PTHREAD_RWLOCK_PREFER_READER_P (rwlock)
+ currently (otherwise, the writer will take care of wake-up).
+ Likewise, even if we prefer readers, we can be responsible for
+ wake-up (see pthread_rwlock_unlock) if no reader or writer has
+ acquired the lock. We have timed out and thus not consumed a
+ futex wake-up; therefore, if there is no other blocked writer
+ that would consume the wake-up and thus take over responsibility,
+ we need to wake blocked readers. */
+ if ((!PTHREAD_RWLOCK_PREFER_READER_P (rwlock)
+ || ((rwlock->__data.__nr_readers == 0)
+ && (rwlock->__data.__nr_writers_queued == 0)))
&& (rwlock->__data.__nr_readers_queued > 0)
&& (rwlock->__data.__writer == 0))
{