summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorDavid Xu <davidxu@FreeBSD.org>2004-01-17 02:45:37 +0000
committerDavid Xu <davidxu@FreeBSD.org>2004-01-17 02:45:37 +0000
commitcc3782cbc7da606434e3a9b3aa6adf0093fd4f2f (patch)
tree9a5afc1ab068736e470c190a1fa85d4ae3ed2869 /lib/libc
parent6c6b4e5dcd8a7273dd4153b8ee885f4b35a5df1b (diff)
Notes
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gen/sem.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/libc/gen/sem.c b/lib/libc/gen/sem.c
index e37eccd1e00f..e9a918b350ff 100644
--- a/lib/libc/gen/sem.c
+++ b/lib/libc/gen/sem.c
@@ -254,7 +254,19 @@ sem_unlink(const char *name)
return (ksem_unlink(name));
}
-int
+static void
+decrease_nwaiters(void *arg)
+{
+ sem_t *sem = (sem_t *)arg;
+
+ (*sem)->nwaiters--;
+ /*
+ * this function is called from cancellation point,
+ * the mutex should already be hold.
+ */
+ _pthread_mutex_unlock(&(*sem)->lock);
+}
+
sem_wait(sem_t *sem)
{
int retval;
@@ -266,11 +278,15 @@ sem_wait(sem_t *sem)
goto RETURN;
}
+ _pthread_testcancel();
+
_pthread_mutex_lock(&(*sem)->lock);
while ((*sem)->count == 0) {
(*sem)->nwaiters++;
- _pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
+ _pthread_cleanup_push(decrease_nwaiters);
+ pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
+ pthread_cleanup_pop(0);
(*sem)->nwaiters--;
}
(*sem)->count--;