diff --git a/lib/libc/posix/pthread.c b/lib/libc/posix/pthread.c index af2eac8..3aa0c57 100644 --- a/lib/libc/posix/pthread.c +++ b/lib/libc/posix/pthread.c @@ -345,18 +345,22 @@ pthread_cond_destroy(pthread_cond_t *cond) int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { + int status; struct pthread_cond *cnd; uint64_t level; if (*cond == NULL) { - int status = pthread_cond_init(cond, NULL); + status = pthread_cond_init(cond, NULL); if (status != 0) return status; } cnd = *cond; - if (mutex) - pthread_mutex_unlock(mutex); + if (mutex) { + status = pthread_mutex_unlock(mutex); + if (status != 0) + return status; + } CoreMutex_Lock(&cnd->mtx); level = cnd->enter; @@ -367,8 +371,11 @@ pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) OSThreadSleep(0); } - if (mutex) - pthread_mutex_lock(mutex); + if (mutex) { + status = pthread_mutex_lock(mutex); + if (status != 0) + return status; + } return 0; } @@ -377,18 +384,24 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) { + int status = 0; + int rstatus = 0; struct pthread_cond *cnd; uint64_t level; + uint64_t endtime = abstime->tv_sec * 1000000000 + abstime->tv_nsec; if (*cond == NULL) { - int status = pthread_cond_init(cond, NULL); + status = pthread_cond_init(cond, NULL); if (status != 0) return status; } cnd = *cond; - if (mutex) - pthread_mutex_unlock(mutex); + if (mutex) { + status = pthread_mutex_unlock(mutex); + if (status != 0) + return status; + } CoreMutex_Lock(&cnd->mtx); level = cnd->enter; @@ -398,13 +411,19 @@ pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, while (level >= cnd->exit) { OSThreadSleep(0); - // XXX: check time + if (endtime < OSTime()) { + rstatus = ETIMEDOUT; + break; + } } - if (mutex) - pthread_mutex_lock(mutex); + if (mutex) { + status = pthread_mutex_lock(mutex); + if (status != 0) + return status; + } - return 0; + return rstatus; }