This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new e45f91f350d sched/signal/sig_dispatch.c: Remove
DEBUGASSERT(!sched_idletask())
e45f91f350d is described below
commit e45f91f350d9e9b5b04f1e0214406e852497aa4d
Author: Jukka Laitinen <[email protected]>
AuthorDate: Wed Oct 29 20:42:45 2025 +0200
sched/signal/sig_dispatch.c: Remove DEBUGASSERT(!sched_idletask())
The DEBUGASSERT is wrong in two cases;
1) In SIM, which does sim_timer_update from the idle task, and the sim
timer runs on signals
2) If signal is dispatched from within an interrupt
In these cases, if there are not available items for pending signals, return
the nxsig_tcbdispatch with -EAGAIN instead of asserting.
Signed-off-by: Jukka Laitinen <[email protected]>
---
sched/signal/sig_dispatch.c | 76 ++++++++++++++++++++++++++++-----------------
1 file changed, 48 insertions(+), 28 deletions(-)
diff --git a/sched/signal/sig_dispatch.c b/sched/signal/sig_dispatch.c
index f65adac2bb6..e1cd559f49a 100644
--- a/sched/signal/sig_dispatch.c
+++ b/sched/signal/sig_dispatch.c
@@ -357,61 +357,76 @@ static FAR sigpendq_t *nxsig_add_pendingsignal(FAR struct
tcb_s *stcb,
*
****************************************************************************/
-static irqstate_t nxsig_alloc_dyn_pending(irqstate_t flags)
+static int nxsig_alloc_dyn_pending(FAR irqstate_t *flags)
{
- if (!up_interrupt_context())
- {
- bool alloc_signal = sq_empty(&g_sigpendingsignal);
- bool alloc_sigact = sq_empty(&g_sigpendingaction);
+ int ret = OK;
+ bool alloc_signal = sq_empty(&g_sigpendingsignal);
+ bool alloc_sigact = sq_empty(&g_sigpendingaction);
- /* Signals are not dispatched from the idle task */
+ if (alloc_signal || alloc_sigact)
+ {
+ FAR sigpendq_t *sigpend = NULL;
+ FAR sigq_t *sigq = NULL;
- DEBUGASSERT(!sched_idletask());
+ /* We can't do memory allocations in idle task or interrupt */
- if (alloc_signal || alloc_sigact)
+ if (up_interrupt_context() || sched_idletask())
{
- FAR sigpendq_t *sigpend = NULL;
- FAR sigq_t *sigq = NULL;
+ return -EAGAIN;
+ }
- /* Leave critical section for the duration of heap operations */
+ /* Leave critical section for the duration of heap operations */
- leave_critical_section(flags);
+ leave_critical_section(*flags);
- /* Allocate more pending signals if there are no more */
+ /* Allocate more pending signals if there are no more */
- if (alloc_signal)
- {
- sigpend = kmm_malloc(sizeof(sigpendq_t));
- }
+ if (alloc_signal)
+ {
+ sigpend = kmm_malloc(sizeof(sigpendq_t));
+ }
- /* Allocate more pending signal actions if there are no more */
+ /* Allocate more pending signal actions if there are no more */
- if (alloc_sigact)
- {
- sigq = kmm_malloc(sizeof(sigq_t));
- }
+ if (alloc_sigact)
+ {
+ sigq = kmm_malloc(sizeof(sigq_t));
+ }
- /* Restore critical section and add the allocated structures to
- * the free pending queues
- */
+ /* Restore critical section and add the allocated structures to
+ * the free pending queues
+ */
- flags = enter_critical_section();
+ *flags = enter_critical_section();
+ if (alloc_signal)
+ {
if (sigpend)
{
sigpend->type = SIG_ALLOC_DYN;
sq_addfirst((sq_entry_t *)sigpend, &g_sigpendingsignal);
}
+ else
+ {
+ ret = -EAGAIN;
+ }
+ }
+ if (alloc_sigact)
+ {
if (sigq)
{
sigq->type = SIG_ALLOC_DYN;
sq_addfirst((sq_entry_t *)sigq, &g_sigpendingaction);
}
+ else
+ {
+ ret = -EAGAIN;
+ }
}
}
- return flags;
+ return ret;
}
/****************************************************************************
@@ -485,7 +500,12 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t
*info,
* needs to be done here before using the task state or sigprocmask.
*/
- flags = nxsig_alloc_dyn_pending(flags);
+ ret = nxsig_alloc_dyn_pending(&flags);
+ if (ret < 0)
+ {
+ leave_critical_section(flags);
+ return ret;
+ }
masked = nxsig_ismember(&stcb->sigprocmask, info->si_signo);