From 3cdae65125db9d867f328391d69970197e4b9556 Mon Sep 17 00:00:00 2001 From: Sam Toyer Date: Fri, 30 Nov 2012 08:57:10 +1000 Subject: [PATCH] sem_timedwait: fix errno, return value and NULL behaviour * Takes into account remarks from Ingo. Signed-off-by: Jerome Duval Signed-off-by: Ingo Weinhold --- src/system/libroot/posix/semaphore.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/system/libroot/posix/semaphore.cpp b/src/system/libroot/posix/semaphore.cpp index b96b8358f7..fb57ced9c3 100644 --- a/src/system/libroot/posix/semaphore.cpp +++ b/src/system/libroot/posix/semaphore.cpp @@ -112,11 +112,25 @@ sem_post(sem_t* semaphore) int sem_timedwait(sem_t* semaphore, const struct timespec* timeout) { - bigtime_t timeoutMicros = ((bigtime_t)timeout->tv_sec) * 1000000 - + timeout->tv_nsec / 1000; + if (timeout != NULL && (timeout->tv_nsec < 0 || + timeout->tv_nsec >= 1000000000)) { + status_t err = _kern_realtime_sem_wait(semaphore->id, 0); + if (err == B_WOULD_BLOCK) + err = EINVAL; + // do nothing, return err as it is. + RETURN_AND_SET_ERRNO_TEST_CANCEL(err); + } - RETURN_AND_SET_ERRNO_TEST_CANCEL( - _kern_realtime_sem_wait(semaphore->id, timeoutMicros)); + bigtime_t timeoutMicros = B_INFINITE_TIMEOUT; + if (timeout != NULL) { + timeoutMicros = ((bigtime_t)timeout->tv_sec) * 1000000 + + timeout->tv_nsec / 1000; + } + status_t err = _kern_realtime_sem_wait(semaphore->id, timeoutMicros); + if (err == B_WOULD_BLOCK) + err = ETIMEDOUT; + + RETURN_AND_SET_ERRNO_TEST_CANCEL(err); }