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);
#ifdef CONFIG_DEBUG
if (!abstime || !sem) {
- err = EINVAL;
+ errcode = EINVAL;
goto errout;
}
#endif
rtcb->waitdog = wd_create();
if (!rtcb->waitdog) {
- err = ENOMEM;
+ errcode = ENOMEM;
goto errout;
}
*/
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) {
- err = EINVAL;
+ errcode = EINVAL;
goto errout_disabled;
}
* 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) {
- err = ETIMEDOUT;
+ if (errcode == OK && ticks <= 0) {
+ 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 */
* cases.
*/
+ if (ret < 0) {
+ /* On failure, restore the errno value returned by sem_wait */
+
+ set_errno(errcode);
+ }
+
return ret;
/* Error exits */
rtcb->waitdog = NULL;
errout:
- set_errno(err);
+ set_errno(errcode);
leave_cancellation_point();
return ERROR;
}