summaryrefslogtreecommitdiff
path: root/nuttx/net
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-09-11 19:31:52 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-09-11 19:31:52 +0000
commita9fda6c0afe5659aa78c92f3b12d3d2bd38bba65 (patch)
tree73408179fdc50341857372673bcb5a51041235d8 /nuttx/net
parent163c619378cab13dce25ab7c933aee34749353ab (diff)
downloadpx4-nuttx-a9fda6c0afe5659aa78c92f3b12d3d2bd38bba65.tar.gz
px4-nuttx-a9fda6c0afe5659aa78c92f3b12d3d2bd38bba65.tar.bz2
px4-nuttx-a9fda6c0afe5659aa78c92f3b12d3d2bd38bba65.zip
Fix race condition that can cause close of socket to hang
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2037 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net')
-rw-r--r--nuttx/net/net_close.c35
-rw-r--r--nuttx/net/uip/uip_tcpinput.c1
2 files changed, 21 insertions, 15 deletions
diff --git a/nuttx/net/net_close.c b/nuttx/net/net_close.c
index eb7dbd711..b05fc338f 100644
--- a/nuttx/net/net_close.c
+++ b/nuttx/net/net_close.c
@@ -158,30 +158,35 @@ static inline void netclose_disconnect(FAR struct socket *psock)
{
struct uip_conn *conn = (struct uip_conn*)psock->s_conn;
- /* Set up to receive TCP data event callbacks */
+ /* Check for the case where the host beat us and disconnected first */
- state.cl_cb = uip_tcpcallbackalloc(conn);
- if (state.cl_cb)
+ if (conn->tcpstateflags == UIP_ESTABLISHED)
{
- state.cl_psock = psock;
- sem_init(&state.cl_sem, 0, 0);
+ /* Set up to receive TCP data event callbacks */
- state.cl_cb->flags = UIP_NEWDATA|UIP_POLL|UIP_CLOSE|UIP_ABORT;
- state.cl_cb->priv = (void*)&state;
- state.cl_cb->event = netclose_interrupt;
+ state.cl_cb = uip_tcpcallbackalloc(conn);
+ if (state.cl_cb)
+ {
+ state.cl_psock = psock;
+ sem_init(&state.cl_sem, 0, 0);
- /* Notify the device driver of the availaibilty of TX data */
+ state.cl_cb->flags = UIP_NEWDATA|UIP_POLL|UIP_CLOSE|UIP_ABORT;
+ state.cl_cb->priv = (void*)&state;
+ state.cl_cb->event = netclose_interrupt;
- netdev_txnotify(&conn->ripaddr);
+ /* Notify the device driver of the availaibilty of TX data */
- /* Wait for the disconnect event */
+ netdev_txnotify(&conn->ripaddr);
- (void)sem_wait(&state.cl_sem);
+ /* Wait for the disconnect event */
- /* We are now disconnected */
+ (void)sem_wait(&state.cl_sem);
- sem_destroy(&state.cl_sem);
- uip_tcpcallbackfree(conn, state.cl_cb);
+ /* We are now disconnected */
+
+ sem_destroy(&state.cl_sem);
+ uip_tcpcallbackfree(conn, state.cl_cb);
+ }
}
}
diff --git a/nuttx/net/uip/uip_tcpinput.c b/nuttx/net/uip/uip_tcpinput.c
index 3fc491f6b..f417c2c7b 100644
--- a/nuttx/net/uip/uip_tcpinput.c
+++ b/nuttx/net/uip/uip_tcpinput.c
@@ -166,6 +166,7 @@ void uip_tcpinput(struct uip_driver_s *dev)
* least queue it it for acceptance).
*/
+ conn->tcpstateflags = UIP_ESTABLISHED;
if (uip_accept(dev, conn, tmp16) != OK)
{
/* No, then we have to give the connection back */