diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index ec2f13b68a..b078402d94 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -35,11 +35,22 @@ #include #include #include +#include #include #include "inode/inode.h" +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct pollfd_s +{ + FAR struct pollfd *fds; + nfds_t nfds; +}; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -160,6 +171,22 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, return ret; } +/**************************************************************************** + * Name: poll_cleanup + * + * Description: + * Setup the poll operation for each descriptor in the list. + * + ****************************************************************************/ + +static void poll_cleanup(FAR void *arg) +{ + FAR struct pollfd_s *fdsinfo = (FAR struct pollfd_s *)arg; + int count; + + poll_teardown(fdsinfo->fds, fdsinfo->nfds, &count, OK); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -414,10 +441,22 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout) kfds = fds; #endif + /* Set up the poll structure */ + nxsem_init(&sem, 0, 0); ret = poll_setup(kfds, nfds, &sem); if (ret >= 0) { + struct pollfd_s fdsinfo; + + /* Push a cancellation point onto the stack. This will be called if + * the thread is canceled. + */ + + fdsinfo.fds = kfds; + fdsinfo.nfds = nfds; + tls_cleanup_push(tls_get_info(), poll_cleanup, &fdsinfo); + if (timeout == 0) { /* Poll returns immediately whether we have a poll event or not. */ @@ -474,6 +513,10 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout) { ret = ret2; } + + /* Pop the cancellation point */ + + tls_cleanup_pop(tls_get_info(), 0); } nxsem_destroy(&sem);