summaryrefslogtreecommitdiff
path: root/src/thread
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-06-26 21:39:15 -0400
committerRich Felker <dalias@aerifal.cx>2013-06-26 21:39:15 -0400
commita033cd22aa0ecd9f494b74669d358e7e1c7e1335 (patch)
tree314164d499b3541346339f2f377c30e405c0d7de /src/thread
parent52d4444f8eec1a4e7e0861859c705c3a558b4e2a (diff)
downloadmusl-a033cd22aa0ecd9f494b74669d358e7e1c7e1335.tar.gz
fix bug whereby sem_open leaked its own internal slots on failure
Diffstat (limited to 'src/thread')
-rw-r--r--src/thread/sem_open.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/thread/sem_open.c b/src/thread/sem_open.c
index 8a72d4c6..66f12ee4 100644
--- a/src/thread/sem_open.c
+++ b/src/thread/sem_open.c
@@ -67,15 +67,15 @@ sem_t *sem_open(const char *name, int flags, ...)
flags &= (O_CREAT|O_EXCL);
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
/* Early failure check for exclusive open; otherwise the case
* where the semaphore already exists is expensive. */
if (flags == (O_CREAT|O_EXCL) && access(name, F_OK) == 0) {
errno = EEXIST;
- return SEM_FAILED;
+ goto fail;
}
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
-
for (;;) {
/* If exclusive mode is not requested, try opening an
* existing file first and fall back to creation. */
@@ -153,6 +153,9 @@ sem_t *sem_open(const char *name, int flags, ...)
fail:
pthread_setcancelstate(cs, 0);
+ LOCK(lock);
+ semtab[slot].sem = 0;
+ UNLOCK(lock);
return SEM_FAILED;
}