diff options
Diffstat (limited to 'nuttx/sched/semaphore/sem_timedwait.c')
-rw-r--r-- | nuttx/sched/semaphore/sem_timedwait.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/nuttx/sched/semaphore/sem_timedwait.c b/nuttx/sched/semaphore/sem_timedwait.c index b7d850728..4d5e58342 100644 --- a/nuttx/sched/semaphore/sem_timedwait.c +++ b/nuttx/sched/semaphore/sem_timedwait.c @@ -167,7 +167,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; irqstate_t flags; int ticks; - int err; + int errcode; int ret = ERROR; DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL); @@ -179,7 +179,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) #ifdef CONFIG_DEBUG if (!abstime || !sem) { - err = EINVAL; + errcode = EINVAL; goto errout; } #endif @@ -192,7 +192,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) rtcb->waitdog = wd_create(); if (!rtcb->waitdog) { - err = ENOMEM; + errcode = ENOMEM; goto errout; } @@ -225,7 +225,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) { - err = EINVAL; + errcode = EINVAL; goto errout_disabled; } @@ -233,31 +233,37 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) * disabled here so that this time stays valid until the wait begins. */ - err = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks); + errcode = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks); /* If the time has already expired return immediately. */ - if (err == OK && ticks <= 0) + if (errcode == OK && ticks <= 0) { - err = ETIMEDOUT; + errcode = ETIMEDOUT; goto errout_disabled; } /* Handle any time-related errors */ - if (err != OK) + if (errcode != OK) { goto errout_disabled; } /* Start the watchdog */ - err = OK; + errcode = OK; wd_start(rtcb->waitdog, ticks, (wdentry_t)sem_timeout, 1, getpid()); /* Now perform the blocking wait */ ret = sem_wait(sem); + if (ret < 0) + { + /* sem_wait() failed. Save the errno value */ + + errcode = get_errno(); + } /* Stop the watchdog timer */ @@ -275,6 +281,13 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) * cases. */ + if (ret < 0) + { + /* On failure, restore the errno value returned by sem_wait */ + + set_errno(errcode); + } + return ret; /* Error exits */ @@ -285,6 +298,6 @@ errout_disabled: rtcb->waitdog = NULL; errout: - set_errno(err); + set_errno(errcode); return ERROR; } |