sched/signal: fix error handling in sigtimedwait()
@@ -280,10 +280,6 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
}
#endif
- /* Save the set of pending signals to wait for */
-
- rtcb->sigwaitmask = *set;
-
/* Check if we should wait for the timeout */
if (timeout != NULL)
@@ -309,6 +305,12 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
waitticks = MSEC2TICK(waitmsec);
#endif
+ if (waitticks > 0)
+ {
+ /* Save the set of pending signals to wait for */
+
+ rtcb->sigwaitmask = *set;
+
/* Start the watchdog */
wd_start(&rtcb->waitdog, waitticks,
@@ -326,11 +328,21 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
wd_cancel(&rtcb->waitdog);
}
+ else
+ {
+ leave_critical_section(flags);
+ return -EAGAIN;
+ }
+ }
/* No timeout, just wait */
else
{
+ /* Save the set of pending signals to wait for */
+
+ rtcb->sigwaitmask = *set;
+
/* And wait until one of the unblocked signals is posted,
* but first make sure this is not the idle task,
* 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))
{
+ /* 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
* 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);
}
