signal/sig_dispatch: Fix case where signal action is sent twice

As far as I can interpret how signal delivery should work when the signal
is blocked, it should still be sent to the pending queue even if the signal
is masked. When the sigmask changes it will be delivered.

The original implementation did not add the pending signal action, if
stcb->task_state == TSTATE_WAIT_SIG is true.

An attempt to patch this was made in #8563 but it is insufficient as it
creates an issue when the task is not waiting for a signal, but is in
syscall, in this case the signal is incorrectly queued twice.
This commit is contained in:
Ville Juven 2023-02-21 11:27:01 +02:00 committed by Xiang Xiao
parent 5ef93ca814
commit be0cb4cbe3
1 changed files with 3 additions and 18 deletions

View File

@ -372,14 +372,9 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)
if (masked == 1) if (masked == 1)
#endif #endif
{ {
#ifdef CONFIG_LIB_SYSCALL /* Add signal to pending queue regardless. */
/* If the thread is in syscall, schedule the sigaction here */
if ((stcb->flags & TCB_FLAG_SYSCALL) != 0) nxsig_add_pendingsignal(stcb, info);
{
nxsig_add_pendingsignal(stcb, info);
}
#endif
/* Check if the task is waiting for this pending signal. If so, then /* Check if the task is waiting for this pending signal. If so, then
* unblock it. This must be performed in a critical section because * unblock it. This must be performed in a critical section because
@ -411,19 +406,9 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)
{ {
up_switch_context(stcb, rtcb); up_switch_context(stcb, rtcb);
} }
leave_critical_section(flags);
} }
/* Its not one we are waiting for... Add it to the list of pending leave_critical_section(flags);
* signals.
*/
else
{
leave_critical_section(flags);
nxsig_add_pendingsignal(stcb, info);
}
} }
/************************* UNMASKED SIGNAL ACTIONS ************************/ /************************* UNMASKED SIGNAL ACTIONS ************************/