From: Ivan Maidanski Date: Sat, 27 Sep 2014 15:30:06 +0000 (+0400) Subject: Fix missing error handling of pthreads_mutex_init and cond_wait X-Git-Tag: gc7_4_4~99 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e82e7232349447c46b7bb64d4309d400a91bbf8f;p=gc Fix missing error handling of pthreads_mutex_init and cond_wait * include/private/darwin_semaphore.h (sem_init): Destroy sem->mutex if sem->cond initialization failed. * include/private/darwin_semaphore.h (sem_post): Ignore pthread_mutex_unlock result in case of pthread_cond_signal. * include/private/darwin_semaphore.h (sem_wait): Unlock mutex and return error (-1) if pthread_cond_wait failed. * include/private/darwin_semaphore.h (sem_init): If pshared then return -1 (with the appropriate errno code set) instead of ABORT. * include/private/darwin_semaphore.h (sem_init, sem_post, sem_wait): Treat non-zero value returned by pthread functions as error (instead of only negative values). * include/private/darwin_semaphore.h (sem_init, sem_post, sem_wait): Reformat code. * misc.c (GC_init): Abort (with the appropriate message) if pthread_mutex[attr]_init failed (SN_TARGET_PS3 case only). * specific.c (GC_key_create_inner): If pthread_mutex_init failed then return its error code. --- diff --git a/include/private/darwin_semaphore.h b/include/private/darwin_semaphore.h index da97b39d..62f185d6 100644 --- a/include/private/darwin_semaphore.h +++ b/include/private/darwin_semaphore.h @@ -34,50 +34,47 @@ typedef struct { } sem_t; GC_INLINE int sem_init(sem_t *sem, int pshared, int value) { - int ret; - if(pshared) - ABORT("sem_init with pshared set"); + if (pshared != 0) { + errno = EPERM; /* unsupported */ + return -1; + } sem->value = value; - - ret = pthread_mutex_init(&sem->mutex,NULL); - if(ret < 0) return -1; - ret = pthread_cond_init(&sem->cond,NULL); - if(ret < 0) return -1; + if (pthread_mutex_init(&sem->mutex, NULL) != 0) + return -1; + if (pthread_cond_init(&sem->cond, NULL) != 0) { + (void)pthread_mutex_destroy(&sem->mutex); + return -1; + } return 0; } GC_INLINE int sem_post(sem_t *sem) { - if(pthread_mutex_lock(&sem->mutex) < 0) - return -1; + if (pthread_mutex_lock(&sem->mutex) != 0) + return -1; sem->value++; - if(pthread_cond_signal(&sem->cond) < 0) { - pthread_mutex_unlock(&sem->mutex); - return -1; + if (pthread_cond_signal(&sem->cond) != 0) { + (void)pthread_mutex_unlock(&sem->mutex); + return -1; } - if(pthread_mutex_unlock(&sem->mutex) < 0) - return -1; - return 0; + return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0; } GC_INLINE int sem_wait(sem_t *sem) { - if(pthread_mutex_lock(&sem->mutex) < 0) - return -1; - while(sem->value == 0) { - pthread_cond_wait(&sem->cond,&sem->mutex); + if (pthread_mutex_lock(&sem->mutex) != 0) + return -1; + while (sem->value == 0) { + if (pthread_cond_wait(&sem->cond, &sem->mutex) != 0) { + (void)pthread_mutex_unlock(&sem->mutex); + return -1; + } } sem->value--; - if(pthread_mutex_unlock(&sem->mutex) < 0) - return -1; - return 0; + return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0; } GC_INLINE int sem_destroy(sem_t *sem) { - int ret; - ret = pthread_cond_destroy(&sem->cond); - if(ret < 0) return -1; - ret = pthread_mutex_destroy(&sem->mutex); - if(ret < 0) return -1; - return 0; + return pthread_cond_destroy(&sem->cond) != 0 + || pthread_mutex_destroy(&sem->mutex) != 0 ? -1 : 0; } #endif diff --git a/misc.c b/misc.c index df434a12..2fcba348 100644 --- a/misc.c +++ b/misc.c @@ -853,8 +853,13 @@ GC_API void GC_CALL GC_init(void) # ifdef SN_TARGET_PS3 { pthread_mutexattr_t mattr; - pthread_mutexattr_init(&mattr); - pthread_mutex_init(&GC_allocate_ml, &mattr); + + if (0 != pthread_mutexattr_init(&mattr)) { + ABORT("pthread_mutexattr_init failed"); + } + if (0 != pthread_mutex_init(&GC_allocate_ml, &mattr)) { + ABORT("pthread_mutex_init failed"); + } pthread_mutexattr_destroy(&mattr); } # endif diff --git a/specific.c b/specific.c index 3657fbad..ba23e47d 100644 --- a/specific.c +++ b/specific.c @@ -26,12 +26,14 @@ static const tse invalid_tse = {INVALID_QTID, 0, 0, INVALID_THREADID}; GC_INNER int GC_key_create_inner(tsd ** key_ptr) { int i; + int ret; tsd * result = (tsd *)MALLOC_CLEAR(sizeof(tsd)); /* A quick alignment check, since we need atomic stores */ GC_ASSERT((word)(&invalid_tse.next) % sizeof(tse *) == 0); if (0 == result) return ENOMEM; - pthread_mutex_init(&(result -> lock), NULL); + ret = pthread_mutex_init(&result->lock, NULL); + if (ret != 0) return ret; for (i = 0; i < TS_CACHE_SIZE; ++i) { result -> cache[i] = (/* no const */ tse *)&invalid_tse; }