This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 276e347e3e1d137a505ff419655f00d37f9f5b81 Author: Marco Casaroli <[email protected]> AuthorDate: Thu Oct 22 12:42:02 2026 +0200 sched/signal: Keep the pending signal of each target apart. All pending signals of a group are in one list; an entry for a signal sent to one thread is marked with that thread. nxsig_add_pendingsignal() looked for an entry with the same signal number only, so a second pending signal for another thread, or for the whole group, was merged into the entry of the first thread. The other thread never got its signal: two threads that block SIGUSR2 and each get one with pthread_kill() saw one signal between them. Look for an entry with the same signal number and the same target (the thread, or the group). POSIX keeps the pending signals of each thread and of the process apart. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- sched/signal/sig_dispatch.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/sched/signal/sig_dispatch.c b/sched/signal/sig_dispatch.c index 4b3585f02bb..01cf27a3b85 100644 --- a/sched/signal/sig_dispatch.c +++ b/sched/signal/sig_dispatch.c @@ -265,7 +265,10 @@ static FAR sigpendq_t *nxsig_alloc_pendingsignal(void) * Name: nxsig_find_pendingsignal * * Description: - * Find a specified element in the pending signal list + * Find the pending signal of one target in the pending signal list: the + * signal sent to the thread 'tcb', or to the whole group if 'tcb' is + * NULL. POSIX keeps the pending signals of each thread and of the + * process apart. * * Assumptions: * Called with group->tg_sigpendingq locked @@ -273,7 +276,8 @@ static FAR sigpendq_t *nxsig_alloc_pendingsignal(void) ****************************************************************************/ static FAR sigpendq_t * -nxsig_find_pendingsignal(FAR struct task_group_s *group, int signo) +nxsig_find_pendingsignal(FAR struct task_group_s *group, int signo, + FAR struct tcb_s *tcb) { FAR sigpendq_t *sigpend = NULL; irqstate_t flags; @@ -294,7 +298,8 @@ nxsig_find_pendingsignal(FAR struct task_group_s *group, int signo) /* Search the list for a action pending on this signal */ for (sigpend = (FAR sigpendq_t *)group->tg_sigpendingq.head; - (sigpend && sigpend->info.si_signo != signo); + (sigpend && (sigpend->info.si_signo != signo || + sigpend->tcb != tcb)); sigpend = sigpend->flink); spin_unlock_irqrestore(&group->tg_lock, flags); @@ -327,9 +332,10 @@ static FAR sigpendq_t *nxsig_add_pendingsignal(FAR struct tcb_s *stcb, DEBUGASSERT(stcb != NULL && stcb->group != NULL); group = stcb->group; - /* Check if the signal is already pending for the group */ + /* Check if the signal is already pending for the same target */ - sigpend = nxsig_find_pendingsignal(group, info->si_signo); + sigpend = nxsig_find_pendingsignal(group, info->si_signo, + group_dispatch ? NULL : stcb); if (sigpend != NULL) { /* The signal is already pending... retain only one copy */
