sched/signal: fix error handling in sigtimedwait()

Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
Petro Karashchenko 2022-11-13 00:50:02 +02:00 committed by Xiang Xiao
parent 12646cc142
commit 1a06ea4356

View File

@ -280,10 +280,6 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
} }
#endif #endif
/* Save the set of pending signals to wait for */
rtcb->sigwaitmask = *set;
/* Check if we should wait for the timeout */ /* Check if we should wait for the timeout */
if (timeout != NULL) if (timeout != NULL)
@ -309,28 +305,44 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
waitticks = MSEC2TICK(waitmsec); waitticks = MSEC2TICK(waitmsec);
#endif #endif
/* Start the watchdog */ if (waitticks > 0)
{
/* Save the set of pending signals to wait for */
wd_start(&rtcb->waitdog, waitticks, rtcb->sigwaitmask = *set;
nxsig_timeout, (uintptr_t)rtcb);
/* Now wait for either the signal or the watchdog, but /* Start the watchdog */
* first, make sure this is not the idle task,
* descheduling that isn't going to end well.
*/
DEBUGASSERT(!is_idle_task(rtcb)); wd_start(&rtcb->waitdog, waitticks,
up_block_task(rtcb, TSTATE_WAIT_SIG); nxsig_timeout, (uintptr_t)rtcb);
/* We no longer need the watchdog */ /* Now wait for either the signal or the watchdog, but
* first, make sure this is not the idle task,
* descheduling that isn't going to end well.
*/
wd_cancel(&rtcb->waitdog); DEBUGASSERT(!is_idle_task(rtcb));
up_block_task(rtcb, TSTATE_WAIT_SIG);
/* We no longer need the watchdog */
wd_cancel(&rtcb->waitdog);
}
else
{
leave_critical_section(flags);
return -EAGAIN;
}
} }
/* No timeout, just wait */ /* No timeout, just wait */
else else
{ {
/* Save the set of pending signals to wait for */
rtcb->sigwaitmask = *set;
/* And wait until one of the unblocked signals is posted, /* And wait until one of the unblocked signals is posted,
* but first make sure this is not the idle task, * but first make sure this is not the idle task,
* descheduling that isn't going to end well. * descheduling that isn't going to end well.
@ -356,6 +368,13 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
if (nxsig_ismember(set, rtcb->sigunbinfo.si_signo)) if (nxsig_ismember(set, rtcb->sigunbinfo.si_signo))
{ {
/* Return the signal info to the caller if so requested */
if (info != NULL)
{
memcpy(info, &rtcb->sigunbinfo, sizeof(struct siginfo));
}
/* Yes.. the return value is the number of the signal that /* Yes.. the return value is the number of the signal that
* awakened us. * awakened us.
*/ */
@ -395,13 +414,6 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
} }
} }
/* Return the signal info to the caller if so requested */
if (info)
{
memcpy(info, &rtcb->sigunbinfo, sizeof(struct siginfo));
}
leave_critical_section(flags); leave_critical_section(flags);
} }