diff options
author | davidxu <davidxu@FreeBSD.org> | 2004-01-17 02:45:37 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2004-01-17 02:45:37 +0000 |
commit | f9aac56ad7dea97108acd58f36d211e416fb0322 (patch) | |
tree | 9a5afc1ab068736e470c190a1fa85d4ae3ed2869 | |
parent | 8a660e960711826394a7a18bfe6a9cfe071e7a21 (diff) | |
download | FreeBSD-src-f9aac56ad7dea97108acd58f36d211e416fb0322.zip FreeBSD-src-f9aac56ad7dea97108acd58f36d211e416fb0322.tar.gz |
Enable cancellation point in sem_wait, it is required by POSIX.
For pshared semaphore, this commit still does not enable cancellation
point, I think there should be a pthread_enter_cancellation_point_np
for libc to implement a safe cancellation point.
-rw-r--r-- | lib/libc/gen/sem.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/libc/gen/sem.c b/lib/libc/gen/sem.c index e37eccd..e9a918b 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--; |