libroot: Treat invalid timespecs as zero-timeouts with a special error code.

Amends b8fdef84a6.

We also now use B_RELATIVE_TIMEOUT in sigtimedwait() rather than
converting to an absolute timeout.

Thanks to korli for the review!
This commit is contained in:
Augustin Cavalier 2024-11-09 14:25:32 -05:00
parent 0b04cf2f5b
commit 3a91fe8d4f
3 changed files with 20 additions and 15 deletions

View File

@ -138,12 +138,9 @@ pthread_mutex_clocklock(pthread_mutex_t* mutex, clockid_t clock_id,
}
status_t status = __pthread_mutex_lock(mutex, flags, timeout);
if (status != B_OK && invalidTime) {
// The timespec was not valid and the mutex could not be locked
// immediately.
return EINVAL;
}
if (status != B_OK && invalidTime)
return EINVAL;
return status;
}

View File

@ -355,9 +355,10 @@ int
pthread_rwlock_clockrdlock(pthread_rwlock_t* lock, clockid_t clock_id,
const struct timespec *abstime)
{
bigtime_t timeout;
bigtime_t timeout = 0;
bool invalidTime = false;
if (abstime == NULL || !timespec_to_bigtime(*abstime, timeout))
return EINVAL;
invalidTime = true;
uint32 flags = 0;
if (timeout >= 0) {
@ -379,7 +380,9 @@ pthread_rwlock_clockrdlock(pthread_rwlock_t* lock, clockid_t clock_id,
else
error = ((LocalRWLock*)lock)->ReadLock(flags, timeout);
return error == B_TIMED_OUT ? EBUSY : error;
if (error != B_OK && invalidTime)
return EINVAL;
return (error == B_TIMED_OUT) ? EBUSY : error;
}
@ -418,9 +421,10 @@ int
pthread_rwlock_clockwrlock(pthread_rwlock_t* lock, clockid_t clock_id,
const struct timespec *abstime)
{
bigtime_t timeout;
bigtime_t timeout = 0;
bool invalidTime = false;
if (abstime == NULL || !timespec_to_bigtime(*abstime, timeout))
return EINVAL;
invalidTime = true;
uint32 flags = 0;
if (timeout >= 0) {
@ -442,7 +446,9 @@ pthread_rwlock_clockwrlock(pthread_rwlock_t* lock, clockid_t clock_id,
else
error = ((LocalRWLock*)lock)->WriteLock(flags, timeout);
return error == B_TIMED_OUT ? EBUSY : error;
if (error != B_OK && invalidTime)
return EINVAL;
return (error == B_TIMED_OUT) ? EBUSY : error;
}

View File

@ -35,12 +35,11 @@ sigtimedwait(const sigset_t* set, siginfo_t* info,
// translate the timeout
uint32 flags;
bigtime_t timeoutMicros = 0;
bool invalidTime = false;
if (timeout != NULL) {
if (!timespec_to_bigtime(*timeout, timeoutMicros))
RETURN_AND_SET_ERRNO(EINVAL);
timeoutMicros += system_time();
flags = B_ABSOLUTE_TIMEOUT;
invalidTime = true;
flags = B_RELATIVE_TIMEOUT;
} else {
flags = 0;
timeoutMicros = 0;
@ -50,6 +49,9 @@ sigtimedwait(const sigset_t* set, siginfo_t* info,
pthread_testcancel();
if (error != B_OK && invalidTime)
error = EINVAL;
if (error != B_OK)
RETURN_AND_SET_ERRNO(error);