diff options
-rw-r--r-- | nuttx/ChangeLog | 4 | ||||
-rw-r--r-- | nuttx/Documentation/NuttX.html | 6 | ||||
-rw-r--r-- | nuttx/include/net/uip/uip-tcp.h | 6 | ||||
-rw-r--r-- | nuttx/net/net_poll.c | 6 | ||||
-rw-r--r-- | nuttx/net/uip/uip_tcpbacklog.c | 19 |
5 files changed, 40 insertions, 1 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 6c138a9f1..b26a42e3a 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -856,3 +856,7 @@ extra two bytes of length cause the driver to sometimes read one too many words from the received FIFO (corrupting the next queued receive packet, if any). + * net/net_poll.c and net/uip/uip_tcpbacklog.c. Fixed an important race condition + bug in polling for connections. The logic worked if the poll was inplace + before the connection was received; but the poll failed to awaken if the + connection was already pending in the backlog when poll() was called. diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html index 2223e362c..37caa7933 100644 --- a/nuttx/Documentation/NuttX.html +++ b/nuttx/Documentation/NuttX.html @@ -8,7 +8,7 @@ <tr align="center" bgcolor="#e4e4e4"> <td> <h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1> - <p>Last Updated: September 09, 2009</p> + <p>Last Updated: September 10, 2009</p> </td> </tr> </table> @@ -1517,6 +1517,10 @@ nuttx-0.4.11 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> extra two bytes of length cause the driver to sometimes read one too many words from the received FIFO (corrupting the next queued receive packet, if any). + * net/net_poll.c and net/uip/uip_tcpbacklog.c. Fixed an important race condition + bug in polling for connections. The logic worked if the poll was inplace + before the connection was received; but the poll failed to awaken if the + connection was already pending in the backlog when poll() was called. pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> diff --git a/nuttx/include/net/uip/uip-tcp.h b/nuttx/include/net/uip/uip-tcp.h index 1fe199e70..4b61c8f2a 100644 --- a/nuttx/include/net/uip/uip-tcp.h +++ b/nuttx/include/net/uip/uip-tcp.h @@ -400,6 +400,11 @@ extern int uip_backlogdestroy(FAR struct uip_conn *conn); /* APIs to manage individual backlog actions */ extern int uip_backlogadd(FAR struct uip_conn *conn, FAR struct uip_conn *blconn); +#ifndef CONFIG_DISABLE_POLL +extern boolean uip_backlogavailable(FAR struct uip_conn *conn); +#else +# define uip_backlogavailable(conn) (FALSE); +#endif extern FAR struct uip_conn *uip_backlogremove(FAR struct uip_conn *conn); extern int uip_backlogdelete(FAR struct uip_conn *conn, FAR struct uip_conn *blconn); @@ -407,6 +412,7 @@ extern int uip_backlogdelete(FAR struct uip_conn *conn, FAR struct uip_conn *blc # define uip_backlogcreate(conn,nblg) (-ENOSYS) # define uip_backlogdestroy(conn) (-ENOSYS) # define uip_backlogadd(conn,blconn) (-ENOSYS) +# define uip_backlogavailable(conn) (FALSE); # define uip_backlogremove(conn) (NULL) #endif diff --git a/nuttx/net/net_poll.c b/nuttx/net/net_poll.c index fac6186c4..0c5e5c75d 100644 --- a/nuttx/net/net_poll.c +++ b/nuttx/net/net_poll.c @@ -201,9 +201,15 @@ static inline int net_pollsetup(FAR struct socket *psock, struct pollfd *fds) fds->priv = (FAR void *)cb; +#ifdef CONFIG_NET_TCPBACKLOG + /* Check for read data or backlogged connection availability now */ + + if (!sq_empty(&conn->readahead) || uip_backlogavailable(conn)) +#else /* Check for read data availability now */ if (!sq_empty(&conn->readahead)) +#endif { fds->revents = fds->events & POLLIN; if (fds->revents != 0) diff --git a/nuttx/net/uip/uip_tcpbacklog.c b/nuttx/net/uip/uip_tcpbacklog.c index 8e6d1fb90..d97acde9c 100644 --- a/nuttx/net/uip/uip_tcpbacklog.c +++ b/nuttx/net/uip/uip_tcpbacklog.c @@ -265,6 +265,25 @@ int uip_backlogadd(FAR struct uip_conn *conn, FAR struct uip_conn *blconn) * Function: uip_backlogremove * * Description: + * Called from poll(). Before waiting for a new connection, poll will + * call this API to see if there are pending connections in the backlog. + * + * Assumptions: + * Called from normal user code, but with interrupts disabled, + * + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_POLL +boolean uip_backlogavailable(FAR struct uip_conn *conn) +{ + return (conn && conn->backlog && !sq_empty(&conn->backlog->bl_pending)); +} +#endif + +/**************************************************************************** + * Function: uip_backlogremove + * + * Description: * Called from accept(). Before waiting for a new connection, accept will * call this API to see if there are pending connections in the backlog. * |