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
This commit is contained in:
patacongo 2009-09-10 22:55:52 +00:00
parent 9a651a8b0e
commit 27ba470482
5 changed files with 40 additions and 1 deletions

View File

@ -856,3 +856,7 @@
extra two bytes of length cause the driver to sometimes read one too many 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, words from the received FIFO (corrupting the next queued receive packet,
if any). 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.

View File

@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4"> <tr align="center" bgcolor="#e4e4e4">
<td> <td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1> <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> </td>
</tr> </tr>
</table> </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 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, words from the received FIFO (corrupting the next queued receive packet,
if any). 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; pascal-0.1.3 2009-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;

View File

@ -400,6 +400,11 @@ extern int uip_backlogdestroy(FAR struct uip_conn *conn);
/* APIs to manage individual backlog actions */ /* APIs to manage individual backlog actions */
extern int uip_backlogadd(FAR struct uip_conn *conn, FAR struct uip_conn *blconn); 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 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); 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_backlogcreate(conn,nblg) (-ENOSYS)
# define uip_backlogdestroy(conn) (-ENOSYS) # define uip_backlogdestroy(conn) (-ENOSYS)
# define uip_backlogadd(conn,blconn) (-ENOSYS) # define uip_backlogadd(conn,blconn) (-ENOSYS)
# define uip_backlogavailable(conn) (FALSE);
# define uip_backlogremove(conn) (NULL) # define uip_backlogremove(conn) (NULL)
#endif #endif

View File

@ -201,9 +201,15 @@ static inline int net_pollsetup(FAR struct socket *psock, struct pollfd *fds)
fds->priv = (FAR void *)cb; 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 */ /* Check for read data availability now */
if (!sq_empty(&conn->readahead)) if (!sq_empty(&conn->readahead))
#endif
{ {
fds->revents = fds->events & POLLIN; fds->revents = fds->events & POLLIN;
if (fds->revents != 0) if (fds->revents != 0)

View File

@ -261,6 +261,25 @@ int uip_backlogadd(FAR struct uip_conn *conn, FAR struct uip_conn *blconn)
return ret; return ret;
} }
/****************************************************************************
* 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 * Function: uip_backlogremove
* *