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-apps.git

commit 3328bbb0be36434c0f543384dcfae0541aceaa85
Author: wangjianyu3 <[email protected]>
AuthorDate: Mon Aug 10 22:34:37 2026 +0800

    system/nxinit: fix on-event actions re-running on every trigger
    
    The `on <event>` action re-executed on every property poll because the
    event pending flag was sticky: event_callback returned the same non-zero
    pending value whether the event had just changed or had stayed satisfied
    from an earlier change. init_action_foreach_event could not distinguish
    an edge from a steady state and re-enqueued the action each round
    (board_netinit ran 262 times per boot).
    
    Introduce a three-state result (EVENT_STATE_UNSATISFIED / SATISFIED /
    TRIGGERED). event_callback now returns TRIGGERED only on the edge where
    pending flips false -> true. foreach folds per-event states into a
    product clamped to TRIGGERED, enqueuing the action only when every event
    is satisfied AND at least one fired this round.
    
    Assisted-by: GitHubCopilot:claude-4.8-opus
    Signed-off-by: wangjianyu3 <[email protected]>
---
 system/nxinit/action.c | 11 +++++------
 system/nxinit/action.h | 12 ++++++++++++
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/system/nxinit/action.c b/system/nxinit/action.c
index a8ce57da8..f1d1d2bfd 100644
--- a/system/nxinit/action.c
+++ b/system/nxinit/action.c
@@ -216,6 +216,7 @@ static int event_callback(FAR struct action_manager_s *am,
           init_debug("Trigger %s%s%s", event->key,
                      event->invert ? "!=" : "==",
                      event->value);
+          return EVENT_STATE_TRIGGERED;
         }
     }
 
@@ -237,20 +238,18 @@ int init_action_foreach_event(FAR struct action_manager_s 
*am,
 
   list_for_every_entry(&am->actions, a, struct action_s, node)
     {
-      for (i = 0, m = 0; i < nitems(a->events) && a->events[i].key; i++)
+      for (i = 0, m = 1; i < nitems(a->events) && a->events[i].key; i++)
         {
           ret = cb(am, a, &a->events[i], arg);
           if (ret < 0)
             {
               break;
             }
-          else if (ret > 0)
-            {
-              m++;
-            }
+
+          m = MIN(m * ret, EVENT_STATE_TRIGGERED);
         }
 
-      if (i > 0 && i == m)
+      if (m == EVENT_STATE_TRIGGERED)
         {
           add_ready(am, a);
         }
diff --git a/system/nxinit/action.h b/system/nxinit/action.h
index 19252f3d0..a13637ed2 100644
--- a/system/nxinit/action.h
+++ b/system/nxinit/action.h
@@ -78,6 +78,18 @@ struct action_manager_s
   FAR struct init_poller_s *prop;
 };
 
+/* Event evaluation result reported by init_action_event_cb.
+ * TRIGGERED means the event is satisfied and its key is the one that just
+ * changed, SATISFIED means it stays satisfied from an earlier change.
+ */
+
+enum action_event_state_e
+{
+  EVENT_STATE_UNSATISFIED = 0,
+  EVENT_STATE_SATISFIED,
+  EVENT_STATE_TRIGGERED,
+};
+
 typedef CODE int (*init_action_event_cb)(FAR struct action_manager_s *,
                                          FAR struct action_s *,
                                          FAR struct action_event_s *,

Reply via email to