From 491a83acb40aa1fa87c1c6894c3ecbe957c19e54 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 13 Sep 2012 20:37:24 +0000 Subject: [PATCH] Fix for recvfrom() hang when the new CONFIG_NET_TCP_RECVDELAY is set to zero (from Max Holtzberg) git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@5148 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/ChangeLog | 4 ++++ nuttx/net/recvfrom.c | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 5728e117f6..1375bea434 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3337,4 +3337,8 @@ * include/nuttx/usb/usb.h, arch/*/src/*usb.c, and arch/*/src/*otg*.c: Add hooks to to use common, external DMA buffer allocation implementation. + * net/recvfrom.c: Don't block in recvfrom if (1) read-ahead buffering + is enabled and (2) some data was obtained from read-ahead buffers. + Blocking is a bad idea in that case because there is no timeout! + (submitted by Max Holtzberg). diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index 51027e0f8a..78990fd39e 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -1079,7 +1079,25 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, else #endif + + /* We get here when we we decide that we need to setup the wait for incoming + * TCP/IP data. Just a few more conditions to check: + * + * 1) Make sure thet there is buffer space to receive additional data + * (state.rf_buflen > 0). This could be zero, for example, if read-ahead + * buffering was enabled and we filled the user buffer with data from + * the read-ahead buffers. Aand + * 2) if read-ahead buffering is enabled (CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0) + * and delay logic is disabled (CONFIG_NET_TCP_RECVDELAY == 0), then we + * not want to wait if we already obtained some data from the read-ahead + * buffer. In that case, return now with what we have. + */ + +#if CONFIG_NET_TCP_RECVDELAY == 0 && CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 + if (state.rf_recvlen == 0 && state.rf_buflen > 0) +#else if (state.rf_buflen > 0) +#endif { struct uip_conn *conn = (struct uip_conn *)psock->s_conn;