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 d6708057583c47419f3fd2dce64adce883b3b523
Author: dongjiuzhu1 <dongjiuz...@xiaomi.com>
AuthorDate: Wed Dec 11 21:32:13 2024 +0800

    system/uorb: add eventfd to notify loop exit.
    
    Add support for exiting loop by writing eventfd.
    
    Signed-off-by: dongjiuzhu1 <dongjiuz...@xiaomi.com>
---
 system/uorb/Kconfig     |  1 +
 system/uorb/Makefile    |  2 ++
 system/uorb/uORB/loop.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
 system/uorb/uORB/uORB.h | 27 ++++++++++++++++++--------
 4 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/system/uorb/Kconfig b/system/uorb/Kconfig
index 3d1d9cb5e..bbe66ca16 100644
--- a/system/uorb/Kconfig
+++ b/system/uorb/Kconfig
@@ -28,6 +28,7 @@ config UORB_TESTS
 
 config UORB_LOOP_MAX_EVENTS
        int "uorb loop max events"
+       depends on EVENT_FD
        default 0
 
 if UORB_TESTS
diff --git a/system/uorb/Makefile b/system/uorb/Makefile
index 800cd5cfb..2811f2f78 100644
--- a/system/uorb/Makefile
+++ b/system/uorb/Makefile
@@ -25,9 +25,11 @@ include $(APPDIR)/Make.defs
 CSRCS    += uORB/uORB.c
 CSRCS    += $(wildcard sensor/*.c)
 
+ifneq ($(CONFIG_UORB_LOOP_MAX_EVENTS),)
 ifneq ($(CONFIG_UORB_LOOP_MAX_EVENTS),0)
 CSRCS    += uORB/loop.c uORB/epoll.c
 endif
+endif
 
 ifneq ($(CONFIG_UORB_LISTENER),)
 MAINSRC  += listener.c
diff --git a/system/uorb/uORB/loop.c b/system/uorb/uORB/loop.c
index 772e37d40..9d9bf994c 100644
--- a/system/uorb/uORB/loop.c
+++ b/system/uorb/uORB/loop.c
@@ -25,6 +25,11 @@
  ****************************************************************************/
 
 #include <errno.h>
+#include <sys/poll.h>
+#include <unistd.h>
+#include <sys/eventfd.h>
+#include <sys/wait.h>
+#include <sys/types.h>
 
 #include "internal.h"
 
@@ -35,6 +40,7 @@
 int orb_loop_init(FAR struct orb_loop_s *loop, enum orb_loop_type_e type)
 {
   int ret = -EINVAL;
+  int fd;
 
   if (loop == NULL)
     {
@@ -57,20 +63,65 @@ int orb_loop_init(FAR struct orb_loop_s *loop, enum 
orb_loop_type_e type)
     {
       uorberr("loop init failed! ret:%d", ret);
       loop->ops = NULL;
+      return ret;
+    }
+
+  fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
+  if (fd < 0)
+    {
+      ret = -errno;
+      uorberr("loop init eventfd failed! ret:%d", ret);
+      goto err_event;
     }
 
+  ret = orb_handle_init(&loop->exit_handle, fd, POLLIN, loop,
+                        NULL, NULL, NULL, NULL);
+  if (ret < 0)
+    {
+      uorberr("loop init eventfd handle init failed! ret:%d", ret);
+      goto err_init;
+    }
+
+  ret = orb_handle_start(loop, &loop->exit_handle);
+  if (ret < 0)
+    {
+      uorberr("loop init eventfd handle start failed! ret:%d", ret);
+      goto err_init;
+    }
+
+  return ret;
+
+err_init:
+  close(fd);
+err_event:
+  orb_loop_deinit(loop);
   return ret;
 }
 
 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);
+        }
+    }
+
+  close(loop->exit_handle.fd);
   ret = loop->ops->uninit(loop);
   if (ret >= 0)
     {
diff --git a/system/uorb/uORB/uORB.h b/system/uorb/uORB/uORB.h
index b1aa15ef2..fb6e172ea 100644
--- a/system/uorb/uORB/uORB.h
+++ b/system/uorb/uORB/uORB.h
@@ -39,6 +39,15 @@
 #include <stdbool.h>
 #include <syslog.h>
 #include <inttypes.h>
+#include <unistd.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_UORB_LOOP_MAX_EVENTS
+#  define CONFIG_UORB_LOOP_MAX_EVENTS 0
+#endif
 
 /****************************************************************************
  * Public Types
@@ -94,14 +103,6 @@ enum orb_loop_type_e
   ORB_EPOLL_TYPE = 0,
 };
 
-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
 {
   int                events;      /* Events of interest. */
@@ -112,6 +113,16 @@ struct orb_handle_s
   orb_eventpri_cb_t  eventpri_cb; /* User EPOLLPRI callback funtion. */
   orb_eventerr_cb_t  eventerr_cb; /* User EPOLLERR callback funtion. */
 };
+
+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
 
 /****************************************************************************

Reply via email to