aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@redhat.com>2017-07-29 00:02:03 -0400
committerAndreas K. Hüttel <dilfridge@gentoo.org>2018-03-04 22:49:26 +0100
commit8eda23a60077f85583aedbc0c5922f04d91401bc (patch)
tree75be903e052d78b4ba04c6cadb675047277da572
parent[no-patch] locale-gen: suppress ignored error when emptying already empty dir... (diff)
downloadglibc-8eda23a60077f85583aedbc0c5922f04d91401bc.tar.gz
glibc-8eda23a60077f85583aedbc0c5922f04d91401bc.tar.bz2
glibc-8eda23a60077f85583aedbc0c5922f04d91401bc.zip
mutex: Fix robust mutex lock acquire (Bug 21778)gentoo/glibc-2.25-15
65810f0ef05e8c9e333f17a44e77808b163ca298 fixed a robust mutex bug but introduced BZ 21778: if the CAS used to try to acquire a lock fails, the expected value is not updated, which breaks other cases in the loce acquisition loop. The fix is to simply update the expected value with the value returned by the CAS, which ensures that behavior is as if the first case with the CAS never happened (if the CAS fails). This is a regression introduced in the last release. Tested on x86_64, i686, ppc64, ppc64le, s390x, aarch64, armv7hl. Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
-rw-r--r--nptl/pthread_mutex_lock.c13
-rw-r--r--nptl/pthread_mutex_timedlock.c13
2 files changed, 16 insertions, 10 deletions
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index dc9ca4c476..4425927c30 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.c
@@ -197,11 +197,14 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
{
/* Try to acquire the lock through a CAS from 0 (not acquired) to
our TID | assume_other_futex_waiters. */
- if (__glibc_likely ((oldval == 0)
- && (atomic_compare_and_exchange_bool_acq
- (&mutex->__data.__lock,
- id | assume_other_futex_waiters, 0) == 0)))
- break;
+ if (__glibc_likely (oldval == 0))
+ {
+ oldval
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+ id | assume_other_futex_waiters, 0);
+ if (__glibc_likely (oldval == 0))
+ break;
+ }
if ((oldval & FUTEX_OWNER_DIED) != 0)
{
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index a4beb7b0dc..dd88cc4ec9 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -154,11 +154,14 @@ pthread_mutex_timedlock (pthread_mutex_t *mutex,
{
/* Try to acquire the lock through a CAS from 0 (not acquired) to
our TID | assume_other_futex_waiters. */
- if (__glibc_likely ((oldval == 0)
- && (atomic_compare_and_exchange_bool_acq
- (&mutex->__data.__lock,
- id | assume_other_futex_waiters, 0) == 0)))
- break;
+ if (__glibc_likely (oldval == 0))
+ {
+ oldval
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+ id | assume_other_futex_waiters, 0);
+ if (__glibc_likely (oldval == 0))
+ break;
+ }
if ((oldval & FUTEX_OWNER_DIED) != 0)
{