summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-16 18:48:29 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-16 18:48:29 +0000
commiteeb84bc3e196548c3c09bd049a648a19e2836f1d (patch)
treef4042ce95d07de6719bf84b76ae29be66bb53b55
parent74e863032ed58ce23f1a0a334f5314d5b1a445bf (diff)
downloadpx4-nuttx-eeb84bc3e196548c3c09bd049a648a19e2836f1d.tar.gz
px4-nuttx-eeb84bc3e196548c3c09bd049a648a19e2836f1d.tar.bz2
px4-nuttx-eeb84bc3e196548c3c09bd049a648a19e2836f1d.zip
Add infrastructure to support poll()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1258 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/ChangeLog1
-rw-r--r--nuttx/Documentation/NuttX.html1
-rw-r--r--nuttx/drivers/bch/bchdev_driver.c3
-rw-r--r--nuttx/drivers/can.c5
-rw-r--r--nuttx/drivers/dev_null.c3
-rw-r--r--nuttx/drivers/dev_zero.c3
-rw-r--r--nuttx/drivers/fifo.c3
-rwxr-xr-xnuttx/drivers/lowconsole.c3
-rw-r--r--nuttx/drivers/pipe.c3
-rw-r--r--nuttx/drivers/serial.c3
-rw-r--r--nuttx/examples/pashello/device.c3
-rw-r--r--nuttx/fs/fs_poll.c228
-rw-r--r--nuttx/include/nuttx/fs.h3
-rw-r--r--nuttx/include/nuttx/net.h8
-rw-r--r--nuttx/net/Makefile2
-rw-r--r--nuttx/net/net-poll.c80
16 files changed, 336 insertions, 16 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 250d6b7d1..53ea69079 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -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
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 79420fa15..98920305b 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -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;
diff --git a/nuttx/drivers/bch/bchdev_driver.c b/nuttx/drivers/bch/bchdev_driver.c
index 9f579bbab..98c7f2991 100644
--- a/nuttx/drivers/bch/bchdev_driver.c
+++ b/nuttx/drivers/bch/bchdev_driver.c
@@ -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 */
};
/****************************************************************************
diff --git a/nuttx/drivers/can.c b/nuttx/drivers/can.c
index e68bfd94d..72e3fdd64 100644
--- a/nuttx/drivers/can.c
+++ b/nuttx/drivers/can.c
@@ -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 */
};
/****************************************************************************
diff --git a/nuttx/drivers/dev_null.c b/nuttx/drivers/dev_null.c
index 5c495451b..f097f76c9 100644
--- a/nuttx/drivers/dev_null.c
+++ b/nuttx/drivers/dev_null.c
@@ -66,7 +66,8 @@ static struct file_operations devnull_fops =
devnull_read, /* read */
devnull_write, /* write */
0, /* seek */
- 0 /* ioctl */
+ 0, /* ioctl */
+ 0 /* poll */
};
/****************************************************************************
diff --git a/nuttx/drivers/dev_zero.c b/nuttx/drivers/dev_zero.c
index a18509415..876734770 100644
--- a/nuttx/drivers/dev_zero.c
+++ b/nuttx/drivers/dev_zero.c
@@ -66,7 +66,8 @@ static struct file_operations devzero_fops =
devzero_read, /* read */
devzero_write, /* write */
0, /* seek */
- 0 /* ioctl */
+ 0, /* ioctl */
+ 0 /* poll */
};
/****************************************************************************
diff --git a/nuttx/drivers/fifo.c b/nuttx/drivers/fifo.c
index 2465d41dc..fb17e3461 100644
--- a/nuttx/drivers/fifo.c
+++ b/nuttx/drivers/fifo.c
@@ -74,7 +74,8 @@ static struct file_operations fifo_fops =
pipecommon_read, /* read */
pipecommon_write, /* write */
0, /* seek */
- 0 /* ioctl */
+ 0, /* ioctl */
+ 0 /* poll */
};
/****************************************************************************
diff --git a/nuttx/drivers/lowconsole.c b/nuttx/drivers/lowconsole.c
index 0dcfe72b3..8b776da19 100755
--- a/nuttx/drivers/lowconsole.c
+++ b/nuttx/drivers/lowconsole.c
@@ -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 */
};
/****************************************************************************
diff --git a/nuttx/drivers/pipe.c b/nuttx/drivers/pipe.c
index 677bcfe4c..7e4581c8a 100644
--- a/nuttx/drivers/pipe.c
+++ b/nuttx/drivers/pipe.c
@@ -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 };
diff --git a/nuttx/drivers/serial.c b/nuttx/drivers/serial.c
index bd4ca33e7..366c7a208 100644
--- a/nuttx/drivers/serial.c
+++ b/nuttx/drivers/serial.c
@@ -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 */
};
/************************************************************************************
diff --git a/nuttx/examples/pashello/device.c b/nuttx/examples/pashello/device.c
index b6db1db5c..fb2deff65 100644
--- a/nuttx/examples/pashello/device.c
+++ b/nuttx/examples/pashello/device.c
@@ -68,7 +68,8 @@ static struct file_operations hello_fops =
hello_read, /* read */
0, /* write */
0, /* seek */
- 0 /* ioctl */
+ 0, /* ioctl */
+ 0 /* poll */
};
/****************************************************************************
diff --git a/nuttx/fs/fs_poll.c b/nuttx/fs/fs_poll.c
index 7b1db1f41..2f585d818 100644
--- a/nuttx/fs/fs_poll.c
+++ b/nuttx/fs/fs_poll.c
@@ -41,16 +41,200 @@
#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;
+
+ 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;
+ }
- errno = ENOSYS;
- return ERROR;
+ return count;
}
diff --git a/nuttx/include/nuttx/fs.h b/nuttx/include/nuttx/fs.h
index 946c60589..65e033208 100644
--- a/nuttx/include/nuttx/fs.h
+++ b/nuttx/include/nuttx/fs.h
@@ -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 */
};
diff --git a/nuttx/include/nuttx/net.h b/nuttx/include/nuttx/net.h
index d4d7ec754..5126e7b65 100644
--- a/nuttx/include/nuttx/net.h
+++ b/nuttx/include/nuttx/net.h
@@ -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
diff --git a/nuttx/net/Makefile b/nuttx/net/Makefile
index b43943396..97c758dd7 100644
--- a/nuttx/net/Makefile
+++ b/nuttx/net/Makefile
@@ -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
diff --git a/nuttx/net/net-poll.c b/nuttx/net/net-poll.c
new file mode 100644
index 000000000..ef4ba9dd3
--- /dev/null
+++ b/nuttx/net/net-poll.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 */