Add infrastructure to support poll()
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@1258 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
parent
e3ce2b3e99
commit
ad069207ff
|
@ -564,3 +564,4 @@
|
|||
types.
|
||||
|
||||
0.3.19 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Add the basic infrastructure for support the poll() API
|
||||
|
|
|
@ -1200,6 +1200,7 @@ buildroot-0.1.2 2007-11-06 <spudmonkey@racsa.co.cr>
|
|||
|
||||
<pre><ul>
|
||||
nuttx-0.3.19 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Add the basic infrastructure for support the poll() API
|
||||
|
||||
pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
|
|
@ -85,7 +85,8 @@ struct file_operations bch_fops =
|
|||
bch_read, /* read */
|
||||
bch_write, /* write */
|
||||
0, /* seek */
|
||||
bch_ioctl /* ioctl */
|
||||
bch_ioctl, /* ioctl */
|
||||
0 /* poll */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -87,8 +87,9 @@ struct file_operations g_canops =
|
|||
can_close, /* close */
|
||||
can_read, /* read */
|
||||
can_write, /* write */
|
||||
0, /* seek */
|
||||
can_ioctl /* ioctl */
|
||||
0, /* seek */
|
||||
can_ioctl, /* ioctl */
|
||||
0 /* poll */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -66,7 +66,8 @@ static struct file_operations devnull_fops =
|
|||
devnull_read, /* read */
|
||||
devnull_write, /* write */
|
||||
0, /* seek */
|
||||
0 /* ioctl */
|
||||
0, /* ioctl */
|
||||
0 /* poll */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -66,7 +66,8 @@ static struct file_operations devzero_fops =
|
|||
devzero_read, /* read */
|
||||
devzero_write, /* write */
|
||||
0, /* seek */
|
||||
0 /* ioctl */
|
||||
0, /* ioctl */
|
||||
0 /* poll */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -74,7 +74,8 @@ static struct file_operations fifo_fops =
|
|||
pipecommon_read, /* read */
|
||||
pipecommon_write, /* write */
|
||||
0, /* seek */
|
||||
0 /* ioctl */
|
||||
0, /* ioctl */
|
||||
0 /* poll */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -75,7 +75,8 @@ struct file_operations g_serialops =
|
|||
lowconsole_read, /* read */
|
||||
lowconsole_write, /* write */
|
||||
0, /* seek */
|
||||
lowconsole_ioctl /* ioctl */
|
||||
lowconsole_ioctl, /* ioctl */
|
||||
0 /* poll */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -82,7 +82,8 @@ static struct file_operations pipe_fops =
|
|||
pipecommon_read, /* read */
|
||||
pipecommon_write, /* write */
|
||||
0, /* seek */
|
||||
0 /* ioctl */
|
||||
0, /* ioctl */
|
||||
0, /* pipe */
|
||||
};
|
||||
|
||||
static sem_t g_pipesem = { 1 };
|
||||
|
|
|
@ -89,7 +89,8 @@ struct file_operations g_serialops =
|
|||
uart_read, /* read */
|
||||
uart_write, /* write */
|
||||
0, /* seek */
|
||||
uart_ioctl /* ioctl */
|
||||
uart_ioctl, /* ioctl */
|
||||
0 /* poll */
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
|
|
|
@ -68,7 +68,8 @@ static struct file_operations hello_fops =
|
|||
hello_read, /* read */
|
||||
0, /* write */
|
||||
0, /* seek */
|
||||
0 /* ioctl */
|
||||
0, /* ioctl */
|
||||
0 /* poll */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -41,15 +41,199 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <poll.h>
|
||||
#include <wdog.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/fs.h>
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include "fs_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define poll_semgive(sem) sem_post(sem)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: poll_semtake
|
||||
****************************************************************************/
|
||||
|
||||
static void poll_semtake(FAR sem_t *sem)
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting) */
|
||||
|
||||
while (sem_wait(sem) != 0)
|
||||
{
|
||||
/* The only case that an error should occur here is if
|
||||
* the wait was awakened by a signal.
|
||||
*/
|
||||
|
||||
ASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: poll_fdsetup
|
||||
*
|
||||
* Description:
|
||||
* Configure (or unconfigure) one file/socket descriptor for the poll
|
||||
* operation. If fds and sem are non-null, then the poll is being setup.
|
||||
* if fds and sem are NULL, then the poll is being torn down.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
static int poll_fdsetup(int fd, FAR struct pollfd *fds)
|
||||
{
|
||||
FAR struct filelist *list;
|
||||
FAR struct file *this_file;
|
||||
FAR struct inode *inode;
|
||||
int ret = -ENOSYS;
|
||||
|
||||
/* Check for a valid file descriptor */
|
||||
|
||||
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
||||
{
|
||||
/* Perform the socket ioctl */
|
||||
|
||||
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
|
||||
{
|
||||
return net_poll(fds->fd, fds);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the thread-specific file list */
|
||||
|
||||
list = sched_getfiles();
|
||||
if (!list)
|
||||
{
|
||||
return -EMFILE;
|
||||
}
|
||||
|
||||
/* Is a driver registered? Does it support the poll method?
|
||||
* If not, return -ENOSYS
|
||||
*/
|
||||
|
||||
this_file = &list->fl_files[fd];
|
||||
inode = this_file->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(this_file, fds);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: poll_setup
|
||||
*
|
||||
* Description:
|
||||
* Setup the poll operation for each descriptor in the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds, sem_t *sem)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Process each descriptor in the list */
|
||||
|
||||
for (i = 0; i < nfds; i++)
|
||||
{
|
||||
/* Setup the poll descriptor */
|
||||
|
||||
fds->sem = sem;
|
||||
fds->revents = 0;
|
||||
|
||||
/* Set up the poll */
|
||||
|
||||
ret = poll_fdsetup(fds->fd, fds);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: poll_teardown
|
||||
*
|
||||
* Description:
|
||||
* Teardown the poll operation for each descriptor in the list and return
|
||||
* the count of non-zero poll events.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count)
|
||||
{
|
||||
int status;
|
||||
int ret = OK;
|
||||
int i;
|
||||
|
||||
/* Process each descriptor in the list */
|
||||
|
||||
for (i = 0; i < nfds; i++)
|
||||
{
|
||||
/* Teardown the poll */
|
||||
|
||||
status = poll_fdsetup(fds->fd, NULL);
|
||||
if (status < 0)
|
||||
{
|
||||
ret = status;
|
||||
}
|
||||
|
||||
/* Check if any events were posted */
|
||||
|
||||
if (fds->revents != 0)
|
||||
{
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
/* Un-initialize the poll structure */
|
||||
|
||||
fds->sem = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: poll_timeout
|
||||
*
|
||||
* Description:
|
||||
* The wdog expired before any other events were received.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void poll_timeout(int argc, uint32 isem)
|
||||
{
|
||||
/* Wake up the poller */
|
||||
|
||||
FAR sem_t *sem = (FAR sem_t *)isem;
|
||||
poll_semgive(sem);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -87,11 +271,45 @@
|
|||
|
||||
int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
{
|
||||
#ifdef CONFIG_CPP_HAVE_WARNING
|
||||
# warning To be provided
|
||||
#endif
|
||||
WDOG_ID wdog;
|
||||
sem_t sem;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
errno = ENOSYS;
|
||||
return ERROR;
|
||||
sem_init(&sem, 0, 0);
|
||||
ret = poll_setup(fds, nfds, &sem);
|
||||
if (ret >= 0)
|
||||
{
|
||||
if (timeout >= 0)
|
||||
{
|
||||
/* Wait for the poll event with a timeout */
|
||||
|
||||
wdog = wd_create();
|
||||
wd_start(wdog, poll_timeout, 1, (uint32)&sem);
|
||||
poll_semtake(&sem);
|
||||
wd_delete(wdog);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait for the poll event with not timeout */
|
||||
|
||||
poll_semtake(&sem);
|
||||
}
|
||||
|
||||
/* Teardown the the poll operation and get the count of events */
|
||||
|
||||
ret = poll_teardown(fds, nfds, &count);
|
||||
}
|
||||
sem_destroy(&sem);
|
||||
|
||||
/* Check for errors */
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
errno = -ret;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
*/
|
||||
|
||||
struct file;
|
||||
struct pollfd;
|
||||
|
||||
struct file_operations
|
||||
{
|
||||
/* The device driver open method differs from the mountpoint open method */
|
||||
|
@ -73,6 +75,7 @@ struct file_operations
|
|||
ssize_t (*write)(FAR struct file *filp, FAR const char *buffer, size_t buflen);
|
||||
off_t (*seek)(FAR struct file *filp, off_t offset, int whence);
|
||||
int (*ioctl)(FAR struct file *filp, int cmd, unsigned long arg);
|
||||
int (*poll)(FAR struct file *filp, struct pollfd *poll);
|
||||
|
||||
/* The two structures need not be common after this point */
|
||||
};
|
||||
|
|
|
@ -153,6 +153,14 @@ EXTERN int net_close(int sockfd);
|
|||
struct ifreq; /* Forward reference -- see net/ioctls.h */
|
||||
EXTERN int netdev_ioctl(int sockfd, int cmd, struct ifreq *req);
|
||||
|
||||
/* net-poll.c ****************************************************************/
|
||||
/* The standard poll() operation redirects operations on socket descriptors
|
||||
* to this function.
|
||||
*/
|
||||
|
||||
struct pollfd; /* Forward reference -- see poll.h */
|
||||
EXTERN int net_poll(int sockfd, struct pollfd *fds);
|
||||
|
||||
/* netdev-register.c *********************************************************/
|
||||
/* This function is called by network interface device drivers to inform the
|
||||
* socket layer of their existence. This registration is necesary to support
|
||||
|
|
|
@ -52,7 +52,7 @@ endif
|
|||
endif
|
||||
|
||||
NETDEV_ASRCS =
|
||||
NETDEV_CSRCS = netdev-register.c netdev-ioctl.c netdev-txnotify.c \
|
||||
NETDEV_CSRCS = netdev-register.c netdev-ioctl.c net-poll.c netdev-txnotify.c \
|
||||
netdev-findbyname.c netdev-findbyaddr.c netdev-count.c \
|
||||
netdev-foreach.c
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/****************************************************************************
|
||||
* net/net-poll.c
|
||||
*
|
||||
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#ifdef CONFIG_NET
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/net.h>
|
||||
#include "net-internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: net_poll
|
||||
*
|
||||
* Description:
|
||||
* The standard poll() operation redirects operations on socket descriptors
|
||||
* to this function.
|
||||
*
|
||||
* Parameters:
|
||||
* fd - The socket descriptor of interest
|
||||
* fds - The structures describing events to be monitored, OR NULL if
|
||||
* this is a request to stop monitoring events.
|
||||
*
|
||||
* Returned Value:
|
||||
* TBD
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int net_poll(int sockfd, struct pollfd *fds)
|
||||
{
|
||||
#ifdef CONFIG_CPP_HAVE_WARNING
|
||||
# warning To be provided
|
||||
#endif
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET */
|
Loading…
Reference in New Issue