summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-09-10 22:55:52 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-09-10 22:55:52 +0000
commitded24f77f6c906ded017b80ccf95755e454af674 (patch)
tree0a8b023170b5ffa3a038685c7432abd8041036d1
parentbe7679e03da5bfac034c384fdd62b70afef88326 (diff)
downloadnuttx-ded24f77f6c906ded017b80ccf95755e454af674.tar.gz
nuttx-ded24f77f6c906ded017b80ccf95755e454af674.tar.bz2
nuttx-ded24f77f6c906ded017b80ccf95755e454af674.zip
Fix race condition bug in poll() for backlogged connections
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2032 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/ChangeLog4
-rw-r--r--nuttx/Documentation/NuttX.html6
-rw-r--r--nuttx/include/net/uip/uip-tcp.h6
-rw-r--r--nuttx/net/net_poll.c6
-rw-r--r--nuttx/net/uip/uip_tcpbacklog.c19
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 &lt;spudmonkey@racsa.co.cr&gt;
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 &lt;spudmonkey@racsa.co.cr&gt;
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.
*