Add the correct implementation of the file_poll() function

This commit is contained in:
Gregory Nutt 2016-07-15 11:34:08 -06:00
parent 6e6c04f778
commit 9ecd558002
3 changed files with 73 additions and 46 deletions

View File

@ -504,32 +504,6 @@ static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
****************************************************************************/
#ifndef CONFIG_DISABLE_POLL
/* REVISIT: There is a file_poll() function, but it does not work in this
* context so the logic is implemented locally as my_file_poll().
*/
static my_file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
{
FAR struct inode *inode;
int ret = -ENOSYS;
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
inode = filep->f_inode;
/* Is a driver registered? Does it support the poll method?
* If not, return -ENOSYS
*/
if (inode != NULL && inode->u.i_ops != NULL && inode->u.i_ops->poll != NULL)
{
/* Yes, then setup the poll */
ret = (int)inode->u.i_ops->poll(filep, fds, setup);
}
return ret;
}
static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
bool setup)
{
@ -544,16 +518,13 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
/* REVISIT: If both POLLIN and POLLOUT are set, might the following logic
* fail? Could we not get POLLIN on the sink file and POLLOUT on the source
* file?
*
* REVISIT: There is a file_poll() function, but it does not work in this
* context so the logic is implemented locally as my_file_poll().
*/
/* POLLIN: Data other than high-priority data may be read without blocking. */
if ((fds->events & POLLIN) != 0)
{
ret = my_file_poll(dev->pd_src, fds, setup);
ret = file_poll(dev->pd_src, fds, setup);
}
if (ret >= OK || ret == -ENOTTY)
@ -562,7 +533,7 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
if ((fds->events & POLLOUT) != 0)
{
ret = my_file_poll(dev->pd_sink, fds, setup);
ret = file_poll(dev->pd_sink, fds, setup);
}
}

View File

@ -243,6 +243,49 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count,
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: file_poll
*
* Description:
* Low-level poll operation based on struc file. This is used both to (1)
* support detached file, and also (2) by fdesc_poll() to perform all
* normal operations on file descriptors descriptors.
*
* Input Parameters:
* file File structure instance
* fds - The structure describing the events to be monitored, OR NULL if
* this is a request to stop monitoring events.
* setup - true: Setup up the poll; false: Teardown the poll
*
* Returned Value:
* 0: Success; Negated errno on failure
*
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
{
FAR struct inode *inode;
int ret = -ENOSYS;
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
inode = filep->f_inode;
/* Is a driver registered? Does it support the poll method?
* If not, return -ENOSYS
*/
if (inode != NULL && inode->u.i_ops != NULL && inode->u.i_ops->poll != NULL)
{
/* Yes, it does... Setup the poll */
ret = (int)inode->u.i_ops->poll(filep, fds, setup);
}
return ret;
}
#endif
/****************************************************************************
* Function: fdesc_poll
*
@ -265,8 +308,6 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count,
int fdesc_poll(int fd, FAR struct pollfd *fds, bool setup)
{
FAR struct file *filep;
FAR struct inode *inode;
int ret = -ENOSYS;
/* Get the file pointer corresponding to this file descriptor */
@ -275,22 +316,14 @@ int fdesc_poll(int fd, FAR struct pollfd *fds, bool setup)
{
/* The errno value has already been set */
return -get_errno();
int errorcode = get_errno();
DEBUGASSERT(errcode > 0);
return -errcode;
}
/* Is a driver registered? Does it support the poll method?
* If not, return -ENOSYS
*/
/* Let file_poll() do the rest */
inode = filep->f_inode;
if (inode && inode->u.i_ops && inode->u.i_ops->poll)
{
/* Yes, then setup the poll */
ret = (int)inode->u.i_ops->poll(filep, fds, setup);
}
return ret;
return file_poll(filep, fds, setup);
}
#endif

View File

@ -929,6 +929,29 @@ int file_ioctl(FAR struct file *filep, int req, unsigned long arg);
int file_vfcntl(FAR struct file *filep, int cmd, va_list ap);
#endif
/****************************************************************************
* Function: file_poll
*
* Description:
* Low-level poll operation based on struc file. This is used both to (1)
* support detached file, and also (2) by fdesc_poll() to perform all
* normal operations on file descriptors descriptors.
*
* Input Parameters:
* file File structure instance
* fds - The structure describing the events to be monitored, OR NULL if
* this is a request to stop monitoring events.
* setup - true: Setup up the poll; false: Teardown the poll
*
* Returned Value:
* 0: Success; Negated errno on failure
*
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup);
#endif
/****************************************************************************
* Function: fdesc_poll
*