Make POSIX semaphores always process shared

Python triggered the undefined behavior previously since it appears to
be posting to a semaphore owned by a different process that wasn't set
to process shared mode. The performance loss to process shared futexes
is so low and semaphores are generally used for this purpose, so it'll
be much simpler to simply not impose undefined behavior here.
This commit is contained in:
Justine Tunney 2023-02-23 08:07:54 -08:00
parent b15f9eb58f
commit 298ba74a45
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
5 changed files with 2 additions and 53 deletions

View file

@ -29,7 +29,6 @@
* @return 0 on success, or -1 w/ errno
*/
int sem_getvalue(sem_t *sem, int *sval) {
_unassert(sem->sem_pshared || sem->sem_pid == getpid());
*sval = atomic_load_explicit(&sem->sem_value, memory_order_relaxed);
return 0;
}

View file

@ -33,11 +33,10 @@
*/
int sem_post(sem_t *sem) {
int rc, old, wakeups;
_unassert(sem->sem_pshared || sem->sem_pid == getpid());
old = atomic_fetch_add_explicit(&sem->sem_value, 1, memory_order_acq_rel);
_unassert(old > INT_MIN);
if (old >= 0) {
wakeups = nsync_futex_wake_(&sem->sem_value, 1, sem->sem_pshared);
wakeups = nsync_futex_wake_(&sem->sem_value, 1, true);
_npassert(wakeups >= 0);
rc = 0;
} else {

View file

@ -75,7 +75,7 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime) {
do {
if (!(v = atomic_load_explicit(&sem->sem_value, memory_order_relaxed))) {
rc = nsync_futex_wait_(&sem->sem_value, v, sem->sem_pshared, abstime);
rc = nsync_futex_wait_(&sem->sem_value, v, true, abstime);
if (rc == -EINTR || rc == -ECANCELED) {
errno = -rc;
rc = -1;

View file

@ -34,7 +34,6 @@
*/
int sem_trywait(sem_t *sem) {
int v;
_unassert(sem->sem_pshared || sem->sem_pid == getpid());
v = atomic_load_explicit(&sem->sem_value, memory_order_relaxed);
do {
_unassert(v > INT_MIN);

View file

@ -42,54 +42,6 @@ TEST(sem_init, einval) {
ASSERT_SYS(EINVAL, -1, sem_init(&sem, 0, -1));
}
TEST(sem_post, accessInChildProcessWhenNotPshared_isUndefinedBehavior) {
if (!IsModeDbg()) return;
int val;
sem_t sem;
ASSERT_SYS(0, 0, sem_init(&sem, 0, 0));
SPAWN(fork);
IgnoreStderr();
sem_post(&sem);
EXITS(77);
}
TEST(sem_getvalue, accessInChildProcessWhenNotPshared_isUndefinedBehavior) {
if (!IsModeDbg()) return;
int val;
sem_t sem;
ASSERT_SYS(0, 0, sem_init(&sem, 0, 0));
ASSERT_SYS(0, 0, sem_getvalue(&sem, &val));
SPAWN(fork);
IgnoreStderr();
sem_getvalue(&sem, &val);
EXITS(77);
ASSERT_SYS(0, 0, sem_destroy(&sem));
}
TEST(sem_timedwait, accessInChildProcessWhenNotPshared_isUndefinedBehavior) {
if (!IsModeDbg()) return;
int val;
sem_t sem;
ASSERT_SYS(0, 0, sem_init(&sem, 0, 0));
SPAWN(fork);
IgnoreStderr();
sem_timedwait(&sem, 0);
EXITS(77);
ASSERT_SYS(0, 0, sem_destroy(&sem));
}
TEST(sem_trywait, accessInChildProcessWhenNotPshared_isUndefinedBehavior) {
if (!IsModeDbg()) return;
int val;
sem_t sem;
ASSERT_SYS(0, 0, sem_init(&sem, 0, 0));
SPAWN(fork);
IgnoreStderr();
sem_trywait(&sem);
EXITS(77);
ASSERT_SYS(0, 0, sem_destroy(&sem));
}
TEST(sem_post, afterDestroyed_isUndefinedBehavior) {
if (!IsModeDbg()) return;
int val;