diff options
Diffstat (limited to 'nuttx/drivers/pipe_common.c')
-rw-r--r-- | nuttx/drivers/pipe_common.c | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/nuttx/drivers/pipe_common.c b/nuttx/drivers/pipe_common.c index cede17ae1..434501559 100644 --- a/nuttx/drivers/pipe_common.c +++ b/nuttx/drivers/pipe_common.c @@ -197,10 +197,6 @@ int pipecommon_open(FAR struct file *filep) } } - /* There is no, file-specific private data (at least not yet) */ - - filep->f_priv = NULL; - /* Increment the reference count on the pipe instance */ dev->d_refs++; @@ -517,58 +513,58 @@ ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer, size_t ****************************************************************************/ #ifndef CONFIG_DISABLE_POLL -int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds) +int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds, + boolean setup) { FAR struct inode *inode = filep->f_inode; FAR struct pipe_dev_s *dev = inode->i_private; pollevent_t eventset; pipe_ndx_t nbytes; + int ret = OK; int i; /* Some sanity checking */ + #if CONFIG_DEBUG - if (!dev) + if (!dev || !fds) { return -ENODEV; } #endif - /* Find an available slot for the poll structure reference */ + /* Are we setting up the poll? Or tearing it down? */ pipecommon_semtake(&dev->d_bfsem); - for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++) + if (setup) { - /* Find the slot with the value equal to filep->f_priv. If there - * is no previously installed poll structure, then f_priv will - * be NULL and we will find the first unused slot. If f_priv is - * is non-NULL, then we will find the slot that was used for the - * previous setup. + /* This is a request to set up the poll. Find an available + * slot for the poll structure reference */ - if (dev->d_fds[i] == filep->f_priv) + for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++) { - dev->d_fds[i] = fds; - break; - } - } + /* Find an available slot */ - if (i >= CONFIG_DEV_PIPE_NPOLLWAITERS) - { - DEBUGASSERT(fds != NULL); - return -EBUSY; - } - - /* Set or clear the poll event structure reference in the 'struct file' - * private data. - */ + if (!dev->d_fds[i]) + { + /* Bind the poll structure and this slot */ - filep->f_priv = fds; + dev->d_fds[i] = fds; + fds->private = &dev->d_fds[i]; + break; + } + } - /* Check if we should immediately notify on any of the requested events */ + if (i >= CONFIG_DEV_PIPE_NPOLLWAITERS) + { + fds->private = NULL; + ret = -EBUSY; + goto errout; + } - if (fds) - { - /* Determine how many bytes are in the buffer */ + /* Should immediately notify on any of the requested events? + * First, determine how many bytes are in the buffer + */ if (dev->d_wrndx >= dev->d_rdndx) { @@ -599,9 +595,29 @@ int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds) pipecommon_pollnotify(dev, eventset); } } + else + { + /* This is a request to tear down the poll. */ + + struct pollfd **slot = (struct pollfd **)fds->private; + +#ifdef CONFIG_DEBUG + if (!slot) + { + ret = -EIO; + goto errout; + } +#endif + + /* Remove all memory of the poll setup */ + + *slot = NULL; + fds->private = NULL; + } +errout: sem_post(&dev->d_bfsem); - return OK; + return ret; } #endif |