[hurd,commited] htl: Fix race between timedrd/wrlock and unlock
Samuel Thibault
samuel.thibault@ens-lyon.org
Wed Mar 4 01:25:49 GMT 2026
In case the rwlock is unlocked right before we time out, we will have been
given ownership, so we shouldn't time out.
Reported-by: Brent Baccala <cosine@freesoft.org> 's Claude assistant
---
sysdeps/htl/pt-rwlock-timedrdlock.c | 41 +++++++++++++----------------
sysdeps/htl/pt-rwlock-timedwrlock.c | 35 +++++++++++-------------
2 files changed, 35 insertions(+), 41 deletions(-)
diff --git a/sysdeps/htl/pt-rwlock-timedrdlock.c b/sysdeps/htl/pt-rwlock-timedrdlock.c
index 41671e40f9..25b761433a 100644
--- a/sysdeps/htl/pt-rwlock-timedrdlock.c
+++ b/sysdeps/htl/pt-rwlock-timedrdlock.c
@@ -31,7 +31,6 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
const struct timespec *abstime)
{
error_t err;
- int drain;
struct __pthread *self;
__pthread_spin_wait (&rwlock->__lock);
@@ -85,35 +84,33 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
__pthread_spin_wait (&rwlock->__lock);
if (self->prevp == NULL)
- /* Another thread removed us from the queue, which means a wakeup message
- has been sent. It was either consumed while we were blocking, or
- queued after we timed out and before we acquired the rwlock lock, in
- which case the message queue must be drained. */
- drain = err ? 1 : 0;
+ {
+ /* Another thread removed us from the queue, which means it gave us
+ ownership and a wakeup message has been sent. It was either consumed
+ while we were blocking, or queued after we timed out and before we
+ acquired the rwlock lock, in which case the message queue must be
+ drained. */
+ __pthread_spin_unlock (&rwlock->__lock);
+ if (err)
+ /* We have not consumed the message, do it now. */
+ __pthread_block (self);
+
+ /* The reader count has already been increment by whoever woke us
+ up. */
+
+ assert (rwlock->__readers > 0);
+
+ return 0;
+ }
else
{
/* We're still in the queue. No one attempted to wake us up, i.e. we
timed out. */
__pthread_dequeue (self);
- drain = 0;
- }
- __pthread_spin_unlock (&rwlock->__lock);
-
- if (drain)
- __pthread_block (self);
-
- if (err)
- {
+ __pthread_spin_unlock (&rwlock->__lock);
assert (err == ETIMEDOUT);
return err;
}
-
- /* The reader count has already been increment by whoever woke us
- up. */
-
- assert (rwlock->__readers > 0);
-
- return 0;
}
int
diff --git a/sysdeps/htl/pt-rwlock-timedwrlock.c b/sysdeps/htl/pt-rwlock-timedwrlock.c
index 6b202a25dd..841d1f9101 100644
--- a/sysdeps/htl/pt-rwlock-timedwrlock.c
+++ b/sysdeps/htl/pt-rwlock-timedwrlock.c
@@ -31,7 +31,6 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
const struct timespec *abstime)
{
error_t err;
- int drain;
struct __pthread *self;
__pthread_spin_wait (&rwlock->__lock);
@@ -71,32 +70,30 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
__pthread_spin_wait (&rwlock->__lock);
if (self->prevp == NULL)
- /* Another thread removed us from the queue, which means a wakeup message
- has been sent. It was either consumed while we were blocking, or
- queued after we timed out and before we acquired the rwlock lock, in
- which case the message queue must be drained. */
- drain = err ? 1 : 0;
+ {
+ /* Another thread removed us from the queue, which means it gave us
+ ownership and a wakeup message has been sent. It was either consumed
+ while we were blocking, or queued after we timed out and before we
+ acquired the rwlock lock, in which case the message queue must be
+ drained. */
+ __pthread_spin_unlock (&rwlock->__lock);
+ if (err)
+ /* We have not consumed the message, do it now. */
+ __pthread_block (self);
+
+ assert (rwlock->__readers == 0);
+
+ return 0;
+ }
else
{
/* We're still in the queue. No one attempted to wake us up, i.e. we
timed out. */
__pthread_dequeue (self);
- drain = 0;
- }
- __pthread_spin_unlock (&rwlock->__lock);
-
- if (drain)
- __pthread_block (self);
-
- if (err)
- {
+ __pthread_spin_unlock (&rwlock->__lock);
assert (err == ETIMEDOUT);
return err;
}
-
- assert (rwlock->__readers == 0);
-
- return 0;
}
int
--
2.51.0
More information about the Libc-alpha
mailing list