Implement poll/select for sockets

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1277 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2008-11-18 17:30:30 +00:00
parent 8e53b72627
commit b2b69f173b
15 changed files with 345 additions and 58 deletions
+1
View File
@@ -571,4 +571,5 @@
full buffer of read data before return. This means that getc would stall when it needed full buffer of read data before return. This means that getc would stall when it needed
to refill the input buffer. The old behavior (read full blocks) might be useful in other to refill the input buffer. The old behavior (read full blocks) might be useful in other
contexts, so it is still available within the driver as a configuration option. contexts, so it is still available within the driver as a configuration option.
* Implement poll() and select() support for TCP/IP sockets
+1
View File
@@ -1207,6 +1207,7 @@ nuttx-0.3.19 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
full buffer of read data before return. This means that getc would stall when it needed full buffer of read data before return. This means that getc would stall when it needed
to refill the input buffer. The old behavior (read full blocks) might be useful in other to refill the input buffer. The old behavior (read full blocks) might be useful in other
contexts, so it is still available within the driver as a configuration option. contexts, so it is still available within the driver as a configuration option.
* Implement poll() and select() support for TCP/IP sockets
pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
+2 -2
View File
@@ -54,7 +54,7 @@
static ssize_t devconsole_read(struct file *, char *, size_t); static ssize_t devconsole_read(struct file *, char *, size_t);
static ssize_t devconsole_write(struct file *, const char *, size_t); static ssize_t devconsole_write(struct file *, const char *, size_t);
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds); static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds, boolean setup);
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -85,7 +85,7 @@ static ssize_t devconsole_write(struct file *filp, const char *buffer, size_t le
} }
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds) static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds, boolean setup)
{ {
return OK; return OK;
} }
+3 -3
View File
@@ -56,7 +56,7 @@
static ssize_t devnull_read(FAR struct file *, FAR char *, size_t); static ssize_t devnull_read(FAR struct file *, FAR char *, size_t);
static ssize_t devnull_write(FAR struct file *, FAR const char *, size_t); static ssize_t devnull_write(FAR struct file *, FAR const char *, size_t);
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
static int devnull_poll(FAR struct file *filp, FAR struct pollfd *poll); static int devnull_poll(FAR struct file *filp, FAR struct pollfd *fds, boolean setup);
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -103,9 +103,9 @@ static ssize_t devnull_write(FAR struct file *filp, FAR const char *buffer, size
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
static int devnull_poll(FAR struct file *filp, FAR struct pollfd *fds) static int devnull_poll(FAR struct file *filp, FAR struct pollfd *fds, boolean setup)
{ {
if (fds) if (setup)
{ {
fds->revents |= (fds->events & (POLLIN|POLLOUT)); fds->revents |= (fds->events & (POLLIN|POLLOUT));
if (fds->revents != 0) if (fds->revents != 0)
+3 -3
View File
@@ -56,7 +56,7 @@
static ssize_t devzero_read(FAR struct file *, FAR char *, size_t); static ssize_t devzero_read(FAR struct file *, FAR char *, size_t);
static ssize_t devzero_write(FAR struct file *, FAR const char *, size_t); static ssize_t devzero_write(FAR struct file *, FAR const char *, size_t);
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
static int devzero_poll(FAR struct file *filp, FAR struct pollfd *fds); static int devzero_poll(FAR struct file *filp, FAR struct pollfd *fds, boolean setup);
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -104,9 +104,9 @@ static ssize_t devzero_write(FAR struct file *filp, FAR const char *buffer, size
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
static int devzero_poll(FAR struct file *filp, FAR struct pollfd *fds) static int devzero_poll(FAR struct file *filp, FAR struct pollfd *fds, boolean setup)
{ {
if (fds) if (setup)
{ {
fds->revents |= (fds->events & (POLLIN|POLLOUT)); fds->revents |= (fds->events & (POLLIN|POLLOUT));
if (fds->revents != 0) if (fds->revents != 0)
+13 -10
View File
@@ -517,7 +517,7 @@ ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer, size_t
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_DISABLE_POLL #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 inode *inode = filep->f_inode;
FAR struct pipe_dev_s *dev = inode->i_private; FAR struct pipe_dev_s *dev = inode->i_private;
@@ -539,7 +539,7 @@ int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds)
for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++) for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++)
{ {
/* Find the slot with the value equal to filep->f_priv. If there /* Find the slot with the value equal to filep->f_priv. If there
* is not previously installed poll structure, then f_priv will * is no previously installed poll structure, then f_priv will
* be NULL and we will find the first unused slot. If f_priv is * 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 * is non-NULL, then we will find the slot that was used for the
* previous setup. * previous setup.
@@ -547,14 +547,14 @@ int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds)
if (dev->d_fds[i] == filep->f_priv) if (dev->d_fds[i] == filep->f_priv)
{ {
dev->d_fds[i] = fds; dev->d_fds[i] = (setup ? fds : NULL);
break; break;
} }
} }
if (i >= CONFIG_DEV_PIPE_NPOLLWAITERS) if (i >= CONFIG_DEV_PIPE_NPOLLWAITERS)
{ {
DEBUGASSERT(fds == NULL); DEBUGASSERT(setup);
return -EBUSY; return -EBUSY;
} }
@@ -562,13 +562,16 @@ int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds)
* private data. * private data.
*/ */
filep->f_priv = fds; filep->f_priv = NULL; /* Assume teardown */
if (setup)
/* Check if we should immediately notify on any of the requested events */
if (fds)
{ {
/* Determine how many bytes are in the buffer */ /* Set the poll event structure reference in the 'struct file' private data. */
filep->f_priv = fds;
/* Check if we 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) if (dev->d_wrndx >= dev->d_rdndx)
{ {
+1 -1
View File
@@ -123,7 +123,7 @@ EXTERN int pipecommon_close(FAR struct file *filep);
EXTERN ssize_t pipecommon_read(FAR struct file *, FAR char *, size_t); EXTERN ssize_t pipecommon_read(FAR struct file *, FAR char *, size_t);
EXTERN ssize_t pipecommon_write(FAR struct file *, FAR const char *, size_t); EXTERN ssize_t pipecommon_write(FAR struct file *, FAR const char *, size_t);
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
EXTERN int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds); EXTERN int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds, boolean setup);
#endif #endif
#undef EXTERN #undef EXTERN
+10 -11
View File
@@ -79,7 +79,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg); static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds); static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, boolean setup);
#endif #endif
/************************************************************************************ /************************************************************************************
@@ -400,7 +400,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
int uart_poll(FAR struct file *filep, FAR struct pollfd *fds) int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, boolean setup)
{ {
FAR struct inode *inode = filep->f_inode; FAR struct inode *inode = filep->f_inode;
FAR uart_dev_t *dev = inode->i_private; FAR uart_dev_t *dev = inode->i_private;
@@ -422,7 +422,7 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds)
for (i = 0; i < CONFIG_DEV_CONSOLE_NPOLLWAITERS; i++) for (i = 0; i < CONFIG_DEV_CONSOLE_NPOLLWAITERS; i++)
{ {
/* Find the slot with the value equal to filep->f_priv. If there /* Find the slot with the value equal to filep->f_priv. If there
* is not previously installed poll structure, then f_priv will * is no previously installed poll structure, then f_priv will
* be NULL and we will find the first unused slot. If f_priv is * 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 * is non-NULL, then we will find the slot that was used for the
* previous setup. * previous setup.
@@ -430,14 +430,14 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds)
if (dev->fds[i] == filep->f_priv) if (dev->fds[i] == filep->f_priv)
{ {
dev->fds[i] = fds; dev->fds[i] = (setup ? fds : NULL);
break; break;
} }
} }
if (i >= CONFIG_DEV_CONSOLE_NPOLLWAITERS) if (i >= CONFIG_DEV_CONSOLE_NPOLLWAITERS)
{ {
DEBUGASSERT(fds == NULL); DEBUGASSERT(setup);
return -EBUSY; return -EBUSY;
} }
@@ -445,13 +445,12 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds)
* private data. * private data.
*/ */
filep->f_priv = fds; filep->f_priv = NULL; /* Assume teardown */
if (setup)
/* Check if we should immediately notify on any of the requested events */
if (fds)
{ {
/* Check if the xmit buffer is full. */ /* Check if we should immediately notify on any of the requested events.
* First, check if the xmit buffer is full.
*/
eventset = 0; eventset = 0;
+4 -4
View File
@@ -93,7 +93,7 @@ static void poll_semtake(FAR sem_t *sem)
****************************************************************************/ ****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
static int poll_fdsetup(int fd, FAR struct pollfd *fds) static int poll_fdsetup(int fd, FAR struct pollfd *fds, boolean setup)
{ {
FAR struct filelist *list; FAR struct filelist *list;
FAR struct file *this_file; FAR struct file *this_file;
@@ -137,7 +137,7 @@ static int poll_fdsetup(int fd, FAR struct pollfd *fds)
{ {
/* Yes, then setup the poll */ /* Yes, then setup the poll */
ret = (int)inode->u.i_ops->poll(this_file, fds); ret = (int)inode->u.i_ops->poll(this_file, fds, setup);
} }
return ret; return ret;
} }
@@ -168,7 +168,7 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds, sem_t *sem)
/* Set up the poll */ /* Set up the poll */
ret = poll_fdsetup(fds[i].fd, &fds[i]); ret = poll_fdsetup(fds[i].fd, &fds[i], TRUE);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@@ -201,7 +201,7 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count)
{ {
/* Teardown the poll */ /* Teardown the poll */
status = poll_fdsetup(fds[i].fd, NULL); status = poll_fdsetup(fds[i].fd, &fds[i], FALSE);
if (status < 0) if (status < 0)
{ {
ret = status; ret = status;
+5 -4
View File
@@ -118,6 +118,7 @@
struct uip_driver_s; /* Forward reference */ struct uip_driver_s; /* Forward reference */
struct uip_callback_s; /* Forward reference */ struct uip_callback_s; /* Forward reference */
struct uip_conn struct uip_conn
{ {
dq_entry_t node; /* Implements a doubly linked list */ dq_entry_t node; /* Implements a doubly linked list */
@@ -179,13 +180,13 @@ struct uip_conn
/* accept() is called when the TCP logic has created a connection */ /* accept() is called when the TCP logic has created a connection */
void *accept_private; FAR void *accept_private;
int (*accept)(struct uip_conn *listener, struct uip_conn *conn); int (*accept)(FAR struct uip_conn *listener, struct uip_conn *conn);
/* connection_event() is called on any of the subset of connection-related events */ /* connection_event() is called on any of the subset of connection-related events */
void *connection_private; FAR void *connection_private;
void (*connection_event)(struct uip_conn *conn, uint16 flags); void (*connection_event)(FAR struct uip_conn *conn, uint16 flags);
}; };
/* The following structure is used to handle read-ahead buffering for TCP /* The following structure is used to handle read-ahead buffering for TCP
+1 -1
View File
@@ -76,7 +76,7 @@ struct file_operations
off_t (*seek)(FAR struct file *filp, off_t offset, int whence); off_t (*seek)(FAR struct file *filp, off_t offset, int whence);
int (*ioctl)(FAR struct file *filp, int cmd, unsigned long arg); int (*ioctl)(FAR struct file *filp, int cmd, unsigned long arg);
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
int (*poll)(FAR struct file *filp, struct pollfd *fds); int (*poll)(FAR struct file *filp, struct pollfd *fds, boolean setup);
#endif #endif
/* The two structures need not be common after this point */ /* The two structures need not be common after this point */
+7 -7
View File
@@ -84,17 +84,17 @@ typedef uint16 socktimeo_t;
struct socket struct socket
{ {
int s_crefs; /* Reference count on the socket */ int s_crefs; /* Reference count on the socket */
uint8 s_type; /* Protocol type: Only SOCK_STREAM or SOCK_DGRAM */ uint8 s_type; /* Protocol type: Only SOCK_STREAM or SOCK_DGRAM */
uint8 s_flags; /* See _SF_* definitions */ uint8 s_flags; /* See _SF_* definitions */
#ifdef CONFIG_NET_SOCKOPTS #ifdef CONFIG_NET_SOCKOPTS
sockopt_t s_options; /* Selected socket options */ sockopt_t s_options; /* Selected socket options */
#ifndef CONFIG_DISABLE_CLOCK #ifndef CONFIG_DISABLE_CLOCK
socktimeo_t s_rcvtimeo; /* Receive timeout value (in deciseconds) */ socktimeo_t s_rcvtimeo; /* Receive timeout value (in deciseconds) */
socktimeo_t s_sndtimeo; /* Send timeout value (in deciseconds) */ socktimeo_t s_sndtimeo; /* Send timeout value (in deciseconds) */
#endif #endif
#endif #endif
void *s_conn; /* Connection: struct uip_conn or uip_udp_conn */ void *s_conn; /* Connection: struct uip_conn or uip_udp_conn */
}; };
/* This defines a list of sockets indexed by the socket descriptor */ /* This defines a list of sockets indexed by the socket descriptor */
+6
View File
@@ -108,6 +108,12 @@ struct pollfd
sem_t *sem; /* Pointer to semaphore used to post output event */ sem_t *sem; /* Pointer to semaphore used to post output event */
pollevent_t events; /* The input event flags */ pollevent_t events; /* The input event flags */
pollevent_t revents; /* The output event flags */ pollevent_t revents; /* The output event flags */
/* The socket poll logic needs a place to retain state info */
#if CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET_TCP) && CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
FAR void *private;
#endif
}; };
/**************************************************************************** /****************************************************************************
+3 -3
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* net-internal.h * net/net-internal.h
* *
* Copyright (C) 2007 Gregory Nutt. All rights reserved. * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -14,7 +14,7 @@
* notice, this list of conditions and the following disclaimer in * notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the * the documentation and/or other materials provided with the
* distribution. * distribution.
* 3. Neither the name Gregory Nutt nor the names of its contributors may be * 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software * used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
+285 -9
View File
@@ -49,7 +49,231 @@
#include "net-internal.h" #include "net-internal.h"
/**************************************************************************** /****************************************************************************
* Global Functions * Pre-processor Definitions
****************************************************************************/
/* Network polling can only be supported on TCP and only if read-ahead buffering
* is enabled (it could be supported on UDP as will if it also had read-ahead
* buffering.
*/
#if defined(CONFIG_DISABLE_POLL) && CONFIG_NSOCKET_DESCRIPTORS > 0 && \
defined(CONFIG_NET_TCP) && CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
# define HAVE_NETPOLL 1
#else
# undef HAVE_NETPOLL
#endif
/****************************************************************************
* Private Types
****************************************************************************/
struct net_poll_s
{
FAR struct pollfd *fds; /* The descriptor poll info */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Function: poll_interrupt
*
* Description:
* This function is called from the interrupt level to perform the actual
* TCP receive operation via by the uIP layer.
*
* Parameters:
* dev The structure of the network driver that caused the interrupt
* conn The connection structure associated with the socket
* flags Set of events describing why the callback was invoked
*
* Returned Value:
* None
*
* Assumptions:
* Running at the interrupt level
*
****************************************************************************/
#ifdef HAVE_NETPOLL
static uint16 poll_interrupt(struct uip_driver_s *dev, FAR void *conn,
FAR void *pvprivate, uint16 flags)
{
struct pollfd *fds = (struct recvfrom_s *)pvprivate;
nvdbg("flags: %04x\n", flags);
/* 'private' might be null in some race conditions (?) */
if (fds)
{
pollevent_t eventset = 0;
/* Check for data availability events. */
if ((flags & UIP_NEWDATA) != 0)
{
eventset |= POLLIN & fds->events;
}
/* A poll is a sign that we are free to send data. */
if ((flags & UIP_POLL) != 0)
{
eventset |= POLLOUT & fds->events;
}
/* Check for a loss of connection events */
if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
{
eventset |= (POLLERR|POLLHUP);
}
if (eventset)
{
fds->revevents |= eventset;
sem_post(fds->sem);
}
}
return flags;
}
#endif /* HAVE_NETPOLL */
/****************************************************************************
* Function: net_pollsetup
*
* Description:
* Setup to monitor events on one TCP/IP socket
*
* Input Parameters:
* conn - The TCP/IP connection of interest
* fds - The structure describing the events to be monitored, OR NULL if
* this is a request to stop monitoring events.
*
* Returned Value:
* 0: Success; Negated errno on failure
*
****************************************************************************/
#ifdef HAVE_NETPOLL
static inline int net_pollsetup((FAR struct uip_conn *)conn, struct pollfd *fds)
{
FAR struct uip_callback_s *cb;
irqstate_t flags;
int ret;
/* Sanity check */
#ifdef CONFIG_DEBUG
if (!conn || !fds || fds->private)
{
ret = -EINVAL;
goto errout;
}
#endif
/* Some of the following must be atomic */
flags = irqsave();
/* Allocate a TCP/IP callback structure */
cb = uip_tcpcallbackalloc(conn);
if (!cb)
{
ret = -EBUSY;
goto errout_with_irq;
}
/* Initialize the callbcack structure */
cb->flags = UIP_NEWDATA|UIP_POLL|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT;
cb->private = (FAR void *)fds;
cb->event = poll_interrupt;
/* Save the nps reference in the poll structure for use at teardown as well */
fds->private = (FAR void *)cb;
/* Check for read data availability now */
if (!sq_empty(&conn->readahead))
{
fds->revents = fds->events & POLLIN;
if (fds->revents != 0)
{
/* If data is available now, the signal the poll logic */
sem_post(fds->sem);
}
}
irqrestore(flags);
return OK;
errout_with_irq:
irqrestore(flags);
free(nps);
errout:
return ret;
}
#endif /* HAVE_NETPOLL */
/****************************************************************************
* Function: net_pollteardown
*
* Description:
* Teardown monitoring of events on an TCP/IP socket
*
* Input Parameters:
* conn - The TCP/IP connection of interest
*
* Returned Value:
* 0: Success; Negated errno on failure
*
****************************************************************************/
#ifdef HAVE_NETPOLL
static inline int net_pollteardown((FAR struct uip_conn *)conn, struct pollfd *fds)
{
FAR struct uip_callback_s *cb;
irqstate_t flags;
int ret;
/* Sanity check */
#ifdef CONFIG_DEBUG
if (!conn || !fds || !fds->private)
{
ret = -EINVAL;
goto errout;
}
#endif
/* Recover the socket descriptor poll state info from the poll structure */
cb = (FAR struct uip_callback_s *)fds->private;
if (cb)
{
/* Release the callback */
flags = irqsave();
uip_tcpcallbackfree(conn, cb);
irqrestore(flags);
/* Release the poll/select data slot */
fds->private = NULL;
}
return OK;
}
#endif /* HAVE_NETPOLL */
/****************************************************************************
* Public Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
@@ -59,22 +283,74 @@
* The standard poll() operation redirects operations on socket descriptors * The standard poll() operation redirects operations on socket descriptors
* to this function. * to this function.
* *
* Parameters: * Input Parameters:
* fd - The socket descriptor of interest * fd - The socket descriptor of interest
* fds - The structures describing events to be monitored, OR NULL if * fds - The structure describing the events to be monitored, OR NULL if
* this is a request to stop monitoring events. * this is a request to stop monitoring events.
* *
* Returned Value: * Returned Value:
* TBD * 0: Success; Negated errno on failure
* *
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_DISABLE_POLL
int net_poll(int sockfd, struct pollfd *fds) int net_poll(int sockfd, struct pollfd *fds)
{ {
#ifdef CONFIG_CPP_HAVE_WARNING #ifndef HAVE_NETPOLL
# warning To be provided
#endif
return -ENOSYS; return -ENOSYS;
} #else
FAR struct socket *psock;
int ret;
#endif /* CONFIG_NET&& !CONFIG_DISABLE_POLL */ /* Verify that non-NULL pointers were passed */
#ifdef CONFIG_DEBUG
if (!fds)
{
ret = -EINVAL;
goto errout;
}
#endif
/* Get the underlying socket structure and verify that the sockfd
* corresponds to valid, allocated socket
*/
psock = sockfd_socket(sockfd);
if (!psock || psock->s_crefs <= 0)
{
ret = -EBADF;
goto errout;
}
#ifdef CONFIG_NET_UDP
/* poll() not supported for UDP */
if (psock->s_type != SOCK_STREAM)
{
ret = -ENOSYS;
goto errout;
}
#endif
/* Check if we are setting up or tearing down the poll */
if (fds)
{
/* Perform the TCP/IP poll() setup */
ret = net_pollsetup((FAR struct uip_conn *)psock->conn, fds);
}
else
{
/* Perform the TCP/IP poll() teardown */
ret = net_pollteardown((FAR struct uip_conn *)psock->conn);
}
errout:
return ret;
#endif /* HAVE_NETPOLL */
}
#endif /* !CONFIG_DISABLE_POLL */
#endif /* CONFIG_NET && !CONFIG_DISABLE_POLL */