mirror of
https://github.com/apache/nuttx-apps.git
synced 2025-10-18 00:11:20 +08:00
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:
@@ -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)
|
||||
{
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
*
|
||||
|
Reference in New Issue
Block a user