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

commit 39f54c15240901cde4cfdfec766d0778a476df10
Author: wangchengdong <[email protected]>
AuthorDate: Wed Oct 29 10:38:17 2025 +0800

    sched/event: Add nxevent_wait_irq() to handle the task cancel
    
        If the thread is blocked waiting on a event, then the
        thread must be unblocked from the evnet to handle
        the task cancellation.
    
    Signed-off-by: Chengdong Wang [email protected]
---
 sched/event/CMakeLists.txt  |  3 +-
 sched/event/Make.defs       |  1 +
 sched/event/event.h         |  5 ++-
 sched/event/event_post.c    |  2 +
 sched/event/event_wait.c    |  9 +++--
 sched/event/event_waitirq.c | 92 +++++++++++++++++++++++++++++++++++++++++++++
 sched/task/task_cancelpt.c  | 12 ++++++
 7 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/sched/event/CMakeLists.txt b/sched/event/CMakeLists.txt
index f823773953d..0791055ff2c 100644
--- a/sched/event/CMakeLists.txt
+++ b/sched/event/CMakeLists.txt
@@ -32,7 +32,8 @@ if(CONFIG_SCHED_EVENTS)
     event_destroy.c
     event_wait.c
     event_clear.c
-    event_getmask.c)
+    event_getmask.c
+    event_waitirq.c)
 endif()
 
 target_sources(sched PRIVATE ${CSRCS})
diff --git a/sched/event/Make.defs b/sched/event/Make.defs
index d6e04059ed2..0c72072e69e 100644
--- a/sched/event/Make.defs
+++ b/sched/event/Make.defs
@@ -24,6 +24,7 @@
 
 ifeq ($(CONFIG_SCHED_EVENTS),y)
   CSRCS += event_init.c event_post.c event_reset.c event_destroy.c 
event_wait.c event_clear.c event_getmask.c
+  CSRCS += event_waitirq.c
 endif
 
 # Include event build support
diff --git a/sched/event/event.h b/sched/event/event.h
index 83c477f6648..e89a26a569f 100644
--- a/sched/event/event.h
+++ b/sched/event/event.h
@@ -31,12 +31,13 @@
 
 #include <nuttx/irq.h>
 #include <nuttx/list.h>
-#include <nuttx/semaphore.h>
 
 #include <nuttx/event.h>
 
 /****************************************************************************
- * Public Type Definitions
+ * Public Function Definitions
  ****************************************************************************/
 
+void nxevent_wait_irq(FAR struct tcb_s *wtcb, int errcode);
+
 #endif /* __SCHED_EVENT_EVENT_H */
diff --git a/sched/event/event_post.c b/sched/event/event_post.c
index c717d58eec7..db1630cd471 100644
--- a/sched/event/event_post.c
+++ b/sched/event/event_post.c
@@ -118,6 +118,8 @@ int nxevent_post(FAR nxevent_t *event, nxevent_mask_t 
events,
 
               wtcb = wait->wtcb;
 
+              wtcb->waitobj = NULL;
+
               /* Remove the task from waiting list */
 
               dq_rem((FAR dq_entry_t *)wtcb, list_waitingforsignal());
diff --git a/sched/event/event_wait.c b/sched/event/event_wait.c
index b9e1b7c971c..e55cb4dbe49 100644
--- a/sched/event/event_wait.c
+++ b/sched/event/event_wait.c
@@ -60,8 +60,8 @@ static void nxevent_timeout(wdparm_t arg)
 
   /* Get waiting tcb from parameter */
 
-  wait = (FAR nxevent_wait_t *)(uintptr_t)arg;
-  wtcb = wait->wtcb;
+  wtcb = (FAR struct tcb_s *)(uintptr_t)arg;
+  wait = wtcb->waitobj;
 
   /* We must be in a critical section in order to call up_switch_context()
    * below.
@@ -82,6 +82,8 @@ static void nxevent_timeout(wdparm_t arg)
           list_delete(&(wait->node));
         }
 
+      wtcb->waitobj = NULL;
+
       /* Mark the errno value for the thread. */
 
       wtcb->errcode = ETIMEDOUT;
@@ -199,13 +201,14 @@ nxevent_mask_t nxevent_tickwait_wait(FAR nxevent_t *event,
       /* Initialize event wait */
 
       wtcb = this_task();
+      wtcb->waitobj = (FAR void *)wait;
       wait->expect = events;
       wait->eflags = eflags;
       wait->wtcb = wtcb;
 
       list_add_tail(&event->list, &(wait->node));
 
-      wd_start(&wtcb->waitdog, delay, nxevent_timeout, (uintptr_t)&wait);
+      wd_start(&wtcb->waitdog, delay, nxevent_timeout, (uintptr_t)wtcb);
 
       /* Remove the tcb task from the ready-to-run list. */
 
diff --git a/sched/event/event_waitirq.c b/sched/event/event_waitirq.c
new file mode 100644
index 00000000000..6bd3dffffa1
--- /dev/null
+++ b/sched/event/event_waitirq.c
@@ -0,0 +1,92 @@
+/****************************************************************************
+ * sched/event/event_waitirq.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+#include "event/event.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxevent_wait_irq
+ *
+ * Description:
+ *   An error event has occurred and the event wait must be terminated with
+ *   an error.
+ *
+ ****************************************************************************/
+
+void nxevent_wait_irq(FAR struct tcb_s *wtcb, int errcode)
+{
+  /* It is possible that an interrupt/context switch beat us to the punch
+   * and already changed the task's state.
+   */
+
+  DEBUGASSERT(wtcb != NULL);
+
+  FAR struct tcb_s *rtcb = this_task();
+  FAR nxevent_wait_t *wait = wtcb->waitobj;
+
+  DEBUGASSERT(wait != NULL);
+
+  /* Remove the wait structure from the event's waiting list */
+
+  if (list_in_list(&(wait->node)))
+    {
+      list_delete(&(wait->node));
+    }
+
+  /* Remove the task from the event waiting list */
+
+  dq_rem((FAR dq_entry_t *)wtcb, list_waitingforsignal());
+
+  /* Indicate that the wait is over */
+
+  wtcb->waitobj = NULL;
+
+  /* Store the error code for the thread */
+
+  wtcb->errcode = errcode;
+
+  /* Add the task to the ready-to-run list and perform a context
+   * switch if one is needed.
+   */
+
+  if (nxsched_add_readytorun(wtcb))
+    {
+      up_switch_context(this_task(), rtcb);
+    }
+}
diff --git a/sched/task/task_cancelpt.c b/sched/task/task_cancelpt.c
index f7462a262c9..74d62c255df 100644
--- a/sched/task/task_cancelpt.c
+++ b/sched/task/task_cancelpt.c
@@ -67,6 +67,7 @@
 #include "signal/signal.h"
 #include "mqueue/mqueue.h"
 #include "task/task.h"
+#include "event/event.h"
 
 /****************************************************************************
  * Public Functions
@@ -165,6 +166,17 @@ bool nxnotify_cancellation(FAR struct tcb_s *tcb)
               nxsig_wait_irq(tcb, SIG_CANCEL_TIMEOUT, SI_USER, ECANCELED);
             }
 
+#ifdef CONFIG_SCHED_EVENTS
+          /* If the thread is blocked waiting on a event, then the
+           * thread must be unblocked to handle the cancellation.
+           */
+
+          else if (tcb->task_state == TSTATE_WAIT_EVENT)
+            {
+              nxevent_wait_irq(tcb, ECANCELED);
+            }
+#endif
+
 #if !defined(CONFIG_DISABLE_MQUEUE) || !defined(CONFIG_DISABLE_MQUEUE_SYSV)
           /* If the thread is blocked waiting on a message queue, then
            * the thread must be unblocked to handle the cancellation.

Reply via email to