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 a90c12b6da6d6c94b35ccc58411b98a753598fec
Author: wangjianyu3 <[email protected]>
AuthorDate: Tue Sep 8 13:16:52 2026 +0800

    system/nxinit: retry a service whose spawn failed
    
    init_service_refresh() ignored the return value of init_service_start().
    If spawning a restarting service failed for any reason (e.g.
    posix_spawnp() itself failing), the service stayed SVC_RESTARTING
    forever with nothing left to re-arm its retry timer: this function's
    return value drives the poll timeout in the caller's event loop
    (main()), and a failed spawn does not fork a child, so there is no
    SIGCHLD either to wake it up some other way. If this service happens
    to be the only pending timer, the poll blocks indefinitely and the
    service is never attempted again.
    
    Check the return value and, on failure, feed the service restart
    period into the poll timeout computed by this function, the same way
    a successfully started/still-restarting service already does.
    
    Also move the CLOCK_MONOTONIC read that updates a service's
    time_started from after a successful spawn to before the spawn is
    even attempted, so that time_started stays current on a failed spawn
    too - otherwise, once woken up (by the fix above or by an unrelated
    event), a repeatedly failing service would look permanently overdue
    (elapsed time computed against a stale timestamp) and get retried
    immediately regardless of its restart_period.
    
    Assisted-by: Kiro:claude-sonnet-5
    Signed-off-by: wangjianyu3 <[email protected]>
---
 system/nxinit/service.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/system/nxinit/service.c b/system/nxinit/service.c
index 52719ed95..8fdb7cbe8 100644
--- a/system/nxinit/service.c
+++ b/system/nxinit/service.c
@@ -323,7 +323,11 @@ int init_service_refresh(FAR struct service_manager_s *sm)
           ms = TIMESPEC2MS(diff);
           if (ms >= service->restart_period)
             {
-              init_service_start(service);
+              if (init_service_start(service) < 0)
+                {
+                  min = MIN(min, service->restart_period);
+                }
+
               continue;
             }
 
@@ -466,6 +470,8 @@ int init_service_start(FAR struct service_s *service)
       return -ret;
     }
 
+  clock_gettime(CLOCK_MONOTONIC, &service->time_started);
+
   ret = posix_spawnp(&pid, service->argv[2], NULL, &attr, &service->argv[2],
                      environ);
   posix_spawnattr_destroy(&attr);
@@ -477,7 +483,6 @@ int init_service_start(FAR struct service_s *service)
     }
 
   service->pid = pid;
-  clock_gettime(CLOCK_MONOTONIC, &service->time_started);
   add_flags(service, SVC_RUNNING);
   remove_flags(service, SVC_RESTARTING);
   remove_flags(service, SVC_DISABLED);

Reply via email to