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 <wangjianyu3@xiaomi.com>
This commit is contained in:
wangjianyu3
2025-04-16 21:10:50 +08:00
committed by CeDeROM
parent 3b0181dbd0
commit f14249d1d3
3 changed files with 40 additions and 25 deletions

View File

@@ -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)
{

View File

@@ -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,

View File

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