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 /****************************************************************************