summaryrefslogtreecommitdiff
path: root/sysdeps/nptl/lowlevellock.h
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2016-10-09 19:34:06 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2016-10-09 19:34:06 +0200
commit6772d640a4f4874166a61f1859e1660a2913a89d (patch)
tree839fea4d5dcefab75577cecb563ccad4234eb953 /sysdeps/nptl/lowlevellock.h
parentf98906bbb57cb495b4501afc5f18604ef3a94e2a (diff)
parent7bb5f8a836b916d6ebf7b6921b136e99cea2442d (diff)
Merge commit 'refs/top-bases/t/hurdsig-fixes' into t/hurdsig-fixes
Diffstat (limited to 'sysdeps/nptl/lowlevellock.h')
-rw-r--r--sysdeps/nptl/lowlevellock.h20
1 files changed, 15 insertions, 5 deletions
diff --git a/sysdeps/nptl/lowlevellock.h b/sysdeps/nptl/lowlevellock.h
index 27f41424ea..3890145402 100644
--- a/sysdeps/nptl/lowlevellock.h
+++ b/sysdeps/nptl/lowlevellock.h
@@ -1,5 +1,5 @@
/* Low-level lock implementation. Generic futex-based version.
- Copyright (C) 2005-2015 Free Software Foundation, Inc.
+ Copyright (C) 2005-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -191,14 +191,21 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
that's cast to void. */
/* Unconditionally set FUTEX to 0 (not acquired), releasing the lock. If FUTEX
was >1 (acquired, possibly with waiters), then wake any waiters. The waiter
- that acquires the lock will set FUTEX to >1. */
+ that acquires the lock will set FUTEX to >1.
+ Evaluate PRIVATE before releasing the lock so that we do not violate the
+ mutex destruction requirements. Specifically, we need to ensure that
+ another thread can destroy the mutex (and reuse its memory) once it
+ acquires the lock and when there will be no further lock acquisitions;
+ thus, we must not access the lock after releasing it, or those accesses
+ could be concurrent with mutex destruction or reuse of the memory. */
#define __lll_unlock(futex, private) \
((void) \
({ \
int *__futex = (futex); \
+ int __private = (private); \
int __oldval = atomic_exchange_rel (__futex, 0); \
if (__glibc_unlikely (__oldval > 1)) \
- lll_futex_wake (__futex, 1, private); \
+ lll_futex_wake (__futex, 1, __private); \
}))
#define lll_unlock(futex, private) \
__lll_unlock (&(futex), private)
@@ -209,14 +216,17 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
that's cast to void. */
/* Unconditionally set FUTEX to 0 (not acquired), releasing the lock. If FUTEX
had FUTEX_WAITERS set then wake any waiters. The waiter that acquires the
- lock will set FUTEX_WAITERS. */
+ lock will set FUTEX_WAITERS.
+ Evaluate PRIVATE before releasing the lock so that we do not violate the
+ mutex destruction requirements (see __lll_unlock). */
#define __lll_robust_unlock(futex, private) \
((void) \
({ \
int *__futex = (futex); \
+ int __private = (private); \
int __oldval = atomic_exchange_rel (__futex, 0); \
if (__glibc_unlikely (__oldval & FUTEX_WAITERS)) \
- lll_futex_wake (__futex, 1, private); \
+ lll_futex_wake (__futex, 1, __private); \
}))
#define lll_robust_unlock(futex, private) \
__lll_robust_unlock (&(futex), private)