diff options
Diffstat (limited to 'nptl/pthread_rwlock_timedwrlock.c')
-rw-r--r-- | nptl/pthread_rwlock_timedwrlock.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c index 416f6e2bd5..a759fa997f 100644 --- a/nptl/pthread_rwlock_timedwrlock.c +++ b/nptl/pthread_rwlock_timedwrlock.c @@ -23,6 +23,7 @@ #include <pthreadP.h> #include <sys/time.h> #include <kernel-features.h> +#include <stdbool.h> /* Try to acquire write lock for RWLOCK or return after specfied time. */ @@ -32,6 +33,7 @@ pthread_rwlock_timedwrlock (rwlock, abstime) const struct timespec *abstime; { int result = 0; + bool wake_readers = false; /* Make sure we are alone. */ lll_lock (rwlock->__data.__lock, rwlock->__data.__shared); @@ -136,6 +138,17 @@ pthread_rwlock_timedwrlock (rwlock, abstime) if (err == -ETIMEDOUT) { result = ETIMEDOUT; + /* 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) + && (rwlock->__data.__nr_readers_queued > 0) + && (rwlock->__data.__writer == 0)) + { + ++rwlock->__data.__readers_wakeup; + wake_readers = true; + } break; } } @@ -143,5 +156,10 @@ pthread_rwlock_timedwrlock (rwlock, abstime) /* We are done, free the lock. */ lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared); + /* Might be required after timeouts. */ + if (wake_readers) + lll_futex_wake (&rwlock->__data.__readers_wakeup, INT_MAX, + rwlock->__data.__shared); + return result; } |