9
0
Fork 0

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:
patacongo 2008-11-16 18:48:29 +00:00
parent e3ce2b3e99
commit ad069207ff
16 changed files with 336 additions and 16 deletions

View File

@ -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

View File

@ -1200,6 +1200,7 @@ buildroot-0.1.2 2007-11-06 &lt;spudmonkey@racsa.co.cr&gt
<pre><ul>
nuttx-0.3.19 2008-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
* Add the basic infrastructure for support the poll() API
pascal-0.1.3 2008-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;

View File

@ -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 */
};
/****************************************************************************

View File

@ -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 */
};
/****************************************************************************

View File

@ -66,7 +66,8 @@ static struct file_operations devnull_fops =
devnull_read, /* read */
devnull_write, /* write */
0, /* seek */
0 /* ioctl */
0, /* ioctl */
0 /* poll */
};
/****************************************************************************

View File

@ -66,7 +66,8 @@ static struct file_operations devzero_fops =
devzero_read, /* read */
devzero_write, /* write */
0, /* seek */
0 /* ioctl */
0, /* ioctl */
0 /* poll */
};
/****************************************************************************

View File

@ -74,7 +74,8 @@ static struct file_operations fifo_fops =
pipecommon_read, /* read */
pipecommon_write, /* write */
0, /* seek */
0 /* ioctl */
0, /* ioctl */
0 /* poll */
};
/****************************************************************************

View File

@ -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 */
};
/****************************************************************************

View File

@ -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 };

View File

@ -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 */
};
/************************************************************************************

View File

@ -68,7 +68,8 @@ static struct file_operations hello_fops =
hello_read, /* read */
0, /* write */
0, /* seek */
0 /* ioctl */
0, /* ioctl */
0 /* poll */
};
/****************************************************************************

View File

@ -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;
}

View File

@ -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 */
};

View File

@ -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

View File

@ -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

80
nuttx/net/net-poll.c Normal file
View File

@ -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 */