diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/thread/sem_open.c | 32 | 
1 files changed, 19 insertions, 13 deletions
| diff --git a/src/thread/sem_open.c b/src/thread/sem_open.c index 08f98c25..ed2353c8 100644 --- a/src/thread/sem_open.c +++ b/src/thread/sem_open.c @@ -29,7 +29,7 @@ sem_t *sem_open(const char *name, int flags, ...)  	va_list ap;  	mode_t mode;  	unsigned value; -	int fd, i, e, slot, first=1, cnt; +	int fd, i, e, slot, first=1, cnt, cs;  	sem_t newsem;  	void *map;  	char tmp[64]; @@ -74,6 +74,8 @@ sem_t *sem_open(const char *name, int flags, ...)  		return SEM_FAILED;  	} +	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); +  	for (;;) {  		/* If exclusive mode is not requested, try opening an  		 * existing file first and fall back to creation. */ @@ -83,16 +85,16 @@ sem_t *sem_open(const char *name, int flags, ...)  				if ((map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED ||  				    fstat(fd, &st) < 0) {  					close(fd); -					return SEM_FAILED; +					goto fail;  				}  				close(fd);  				break;  			}  			if (errno != ENOENT) -				return SEM_FAILED; +				goto fail;  		}  		if (!(flags & O_CREAT)) -			return SEM_FAILED; +			goto fail;  		if (first) {  			first = 0;  			va_start(ap, flags); @@ -101,7 +103,7 @@ sem_t *sem_open(const char *name, int flags, ...)  			va_end(ap);  			if (value > SEM_VALUE_MAX) {  				errno = EINVAL; -				return SEM_FAILED; +				goto fail;  			}  			sem_init(&newsem, 1, value);  		} @@ -112,13 +114,13 @@ sem_t *sem_open(const char *name, int flags, ...)  		fd = open(tmp, O_CREAT|O_EXCL|FLAGS, mode);  		if (fd < 0) {  			if (errno == EEXIST) continue; -			return SEM_FAILED; +			goto fail;  		}  		if (write(fd, &newsem, sizeof newsem) != sizeof newsem || fstat(fd, &st) < 0 ||  		    (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {  			close(fd);  			unlink(tmp); -			return SEM_FAILED; +			goto fail;  		}  		close(fd);  		if (link(tmp, name) == 0) break; @@ -128,7 +130,7 @@ sem_t *sem_open(const char *name, int flags, ...)  		 * otherwise, next iteration will try to open the  		 * existing file. */  		if (e != EEXIST || flags == (O_CREAT|O_EXCL)) -			return SEM_FAILED; +			goto fail;  	}  	/* See if the newly mapped semaphore is already mapped. If @@ -138,16 +140,20 @@ sem_t *sem_open(const char *name, int flags, ...)  	for (i=0; i<SEM_NSEMS_MAX && semtab[i].ino != st.st_ino; i++);  	if (i<SEM_NSEMS_MAX) {  		munmap(map, sizeof(sem_t)); -		semtab[i].refcnt++; -		UNLOCK(lock); -		return semtab[i].sem; +		semtab[slot].sem = 0; +		slot = i; +		map = semtab[i].sem;  	} -	semtab[slot].refcnt = 1; +	semtab[slot].refcnt++;  	semtab[slot].sem = map;  	semtab[slot].ino = st.st_ino;  	UNLOCK(lock); - +	pthread_setcancelstate(cs, 0);  	return map; + +fail: +	pthread_setcancelstate(cs, 0); +	return SEM_FAILED;  }  int sem_close(sem_t *sem) | 
