This is an automated email from the ASF dual-hosted git repository.

cederom pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit f14249d1d341fb1345e74b257bdea636a1777996
Author: wangjianyu3 <wangjian...@xiaomi.com>
AuthorDate: Wed Apr 16 21:10:50 2025 +0800

    system/uORB: Add API for sending loop exit event
    
    Add orb_loop_exit_async() API to send exit event to uORB loop.
    
    Closing immediately after a write may cause missing a wakeup.
    
    When all file descriptors associated with the same eventfd object have been 
closed, the resources for object are freed by the kernel. --EVENTFD(2)
    
    Signed-off-by: wangjianyu3 <wangjian...@xiaomi.com>
---
 system/uorb/uORB/epoll.c | 14 +++++---------
 system/uorb/uORB/loop.c  | 34 ++++++++++++++++++++--------------
 system/uorb/uORB/uORB.h  | 17 +++++++++++++++--
 3 files changed, 40 insertions(+), 25 deletions(-)

diff --git a/system/uorb/uORB/epoll.c b/system/uorb/uORB/epoll.c
index 28237acc8..147831d3f 100644
--- a/system/uorb/uORB/epoll.c
+++ b/system/uorb/uORB/epoll.c
@@ -58,7 +58,6 @@ const struct orb_loop_ops_s g_orb_loop_epoll_ops =
 
 static int orb_loop_epoll_init(FAR struct orb_loop_s *loop)
 {
-  loop->running = false;
   loop->fd = epoll_create1(EPOLL_CLOEXEC);
   if (loop->fd < 0)
     {
@@ -75,13 +74,7 @@ static int orb_loop_epoll_run(FAR struct orb_loop_s *loop)
   int nfds;
   int i;
 
-  if (loop->running)
-    {
-      return -EBUSY;
-    }
-
-  loop->running = true;
-  while (loop->running)
+  while (1)
     {
       nfds = epoll_wait(loop->fd, et, CONFIG_UORB_LOOP_MAX_EVENTS, -1);
       if (nfds == -1 && errno != EINTR)
@@ -96,6 +89,10 @@ static int orb_loop_epoll_run(FAR struct orb_loop_s *loop)
             {
               continue;
             }
+          else if (handle == &loop->exit_handle)
+            {
+              return OK;
+            }
 
           if (et[i].events & EPOLLIN)
             {
@@ -151,7 +148,6 @@ static int orb_loop_epoll_uninit(FAR struct orb_loop_s 
*loop)
 {
   int ret;
 
-  loop->running = false;
   ret = close(loop->fd);
   if (ret < 0)
     {
diff --git a/system/uorb/uORB/loop.c b/system/uorb/uORB/loop.c
index 9d9bf994c..01ea5f753 100644
--- a/system/uorb/uORB/loop.c
+++ b/system/uorb/uORB/loop.c
@@ -100,27 +100,14 @@ err_event:
 
 int orb_loop_run(FAR struct orb_loop_s *loop)
 {
-  loop->self = gettid();
   return loop->ops->run(loop);
 }
 
 int orb_loop_deinit(FAR struct orb_loop_s *loop)
 {
-  eventfd_t exit = 1;
   int ret;
 
-  loop->running = false;
-  write(loop->exit_handle.fd, &exit, sizeof(exit));
-
-  if (gettid() != loop->self)
-    {
-      ret = waitpid(loop->self, &ret, 0);
-      if (ret < 0)
-        {
-          uorberr("loop deinit waitpid failed! ret:%d", -errno);
-        }
-    }
-
+  orb_handle_stop(loop, &loop->exit_handle);
   close(loop->exit_handle.fd);
   ret = loop->ops->uninit(loop);
   if (ret >= 0)
@@ -131,6 +118,25 @@ int orb_loop_deinit(FAR struct orb_loop_s *loop)
   return ret;
 }
 
+int orb_loop_exit_async(FAR struct orb_loop_s *loop)
+{
+  eventfd_t exit = 1;
+  ssize_t n;
+
+  if (!loop)
+    {
+      return -EINVAL;
+    }
+
+  n = write(loop->exit_handle.fd, &exit, sizeof(exit));
+  if (n < 0)
+    {
+      return -errno;
+    }
+
+  return n == sizeof(exit) ? OK : ERROR;
+}
+
 int orb_handle_init(FAR struct orb_handle_s *handle, int fd, int events,
                     FAR void *arg, orb_datain_cb_t datain_cb,
                     orb_dataout_cb_t dataout_cb, orb_eventpri_cb_t pri_cb,
diff --git a/system/uorb/uORB/uORB.h b/system/uorb/uORB/uORB.h
index fb6e172ea..5e0bc6c67 100644
--- a/system/uorb/uORB/uORB.h
+++ b/system/uorb/uORB/uORB.h
@@ -118,10 +118,8 @@ struct orb_loop_ops_s;
 struct orb_loop_s
 {
   FAR const struct orb_loop_ops_s *ops;         /* Loop handle ops. */
-  bool                             running;     /* uORB loop is running flag. 
*/
   int                              fd;          /* Loop fd. */
   struct orb_handle_s              exit_handle; /* The exit handle */
-  pid_t                            self;        /* The pid of the loop */
 };
 #endif
 
@@ -959,6 +957,21 @@ int orb_loop_run(FAR struct orb_loop_s *loop);
 
 int orb_loop_deinit(FAR struct orb_loop_s *loop);
 
+/****************************************************************************
+ * Name: orb_loop_exit_async
+ *
+ * Description:
+ *   Send exit event to the current loop(not wait).
+ *
+ * Input Parameters:
+ *   loop   orb loop contains multiple handles.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a -1 (ERROR) or negated errno value on failure.
+ ****************************************************************************/
+
+int orb_loop_exit_async(FAR struct orb_loop_s *loop);
+
 /****************************************************************************
  * Name: orb_handle_init
  *

Reply via email to