From a44ddc4793d7f5da02fd04f795fb479192749cab Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 14 Apr 2021 22:52:33 +0200 Subject: [PATCH] LibPthread: Don't hold sem->mtx after sem_wait()/sem_trywait() Semaphores with values greater than one didn't work because whoever called sem_wait() first held the semaphore's mutex until a matching sem_post() call. Other callers then wouldn't be able to acquire the semaphore even if the semaphore's value was still greater than zero at that point. --- Userland/Libraries/LibPthread/semaphore.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibPthread/semaphore.cpp b/Userland/Libraries/LibPthread/semaphore.cpp index 80fa72554b..d42964103e 100644 --- a/Userland/Libraries/LibPthread/semaphore.cpp +++ b/Userland/Libraries/LibPthread/semaphore.cpp @@ -93,6 +93,12 @@ sem_t* sem_open(const char*, int, ...) int sem_post(sem_t* sem) { + auto rc = pthread_mutex_lock(&sem->mtx); + if (rc != 0) { + errno = rc; + return -1; + } + if (sem->value == SEM_VALUE_MAX) { pthread_mutex_unlock(&sem->mtx); errno = EOVERFLOW; @@ -101,7 +107,7 @@ int sem_post(sem_t* sem) sem->value++; - auto rc = pthread_cond_signal(&sem->cv); + rc = pthread_cond_signal(&sem->cv); if (rc != 0) { pthread_mutex_unlock(&sem->mtx); errno = rc; @@ -133,6 +139,12 @@ int sem_trywait(sem_t* sem) sem->value--; + rc = pthread_mutex_unlock(&sem->mtx); + if (rc != 0) { + errno = rc; + return -1; + } + return 0; } @@ -161,5 +173,11 @@ int sem_wait(sem_t* sem) sem->value--; + rc = pthread_mutex_unlock(&sem->mtx); + if (rc != 0) { + errno = rc; + return -1; + } + return 0; }