From 12b1c0450832b63e1df3de263497e371cd05c3c4 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Fri, 21 Aug 2015 09:15:06 -0600 Subject: [PATCH] recvfrom(): Correct wait for new data when NET_UDP_READAHEAD is enabled. Fix size accounting when recvfrom_udpreadahead() sets state.rf_recvlen == -1. I have not checked if data are accumulated to the right position in the buffer however. Signed-off-by: Pavel Pisa --- ChangeLog | 12 +++++++++++ arch | 2 +- net/socket/recvfrom.c | 49 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f93650473..cad1af1cb5 100755 --- a/ChangeLog +++ b/ChangeLog @@ -10842,3 +10842,15 @@ * arch/arm/src/lpc17/lpc17_irq.c: Set NVIC vector address so that code can execute with a bootloader or can execute from RAM. From Pavel Pisa (2015-08-20). + * All ARMV7-M IRQ setup: Always set the NVIC vector table address + unconditionally. This is needed in cases where the code is running + with a bootload and when the code is running from RAM. It is also + needed by the logic of up_ramvec_initialize() which gets the vector + base address from the NVIC. Suggested by Pavel Pisa (2015-08-21). + * SAMV7 USBHS DCD: The device controller driver is (finally) functional + (2015-08-21). + * recvfrom(): Correct wait for new data when NET_UDP_READAHEAD is + enabled. Fix size accounting when recvfrom_udpreadahead() sets + state.rf_recvlen == -1. I have not checked if data are accumulated + to the right position in the buffer however. From Pavel Pisa + (2015-08-15). diff --git a/arch b/arch index 76efd5e60a..94705f285e 160000 --- a/arch +++ b/arch @@ -1 +1 @@ -Subproject commit 76efd5e60a14c9e3b312b6f11c7c67de972a8299 +Subproject commit 94705f285e98a1ec5ca66027be01eff2e1189e27 diff --git a/net/socket/recvfrom.c b/net/socket/recvfrom.c index 32b2067ffc..09bf4626e1 100644 --- a/net/socket/recvfrom.c +++ b/net/socket/recvfrom.c @@ -110,6 +110,39 @@ struct recvfrom_s * Private Functions ****************************************************************************/ +/**************************************************************************** + * Function: recvfrom_add_recvlen + * + * Description: + * Update information about space available for new data and update size + * of data in buffer, This logic accounts for the case where + * recvfrom_udpreadahead() sets state.rf_recvlen == -1 . + * + * Parameters: + * pstate recvfrom state structure + * recvlen size of new data appended to buffer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) || defined(CONFIG_NET_PKT) + +static inline void recvfrom_add_recvlen(FAR struct recvfrom_s *pstate, + size_t recvlen) +{ + if (pstate->rf_recvlen < 0) + { + pstate->rf_recvlen = 0; + } + + pstate->rf_recvlen += recvlen; + pstate->rf_buffer += recvlen; + pstate->rf_buflen -= recvlen; +} +#endif /* CONFIG_NET_UDP || CONFIG_NET_TCP || CONFIG_NET_PKT */ + /**************************************************************************** * Function: recvfrom_newdata * @@ -152,9 +185,7 @@ static size_t recvfrom_newdata(FAR struct net_driver_s *dev, /* Update the accumulated size of the data read */ - pstate->rf_recvlen += recvlen; - pstate->rf_buffer += recvlen; - pstate->rf_buflen -= recvlen; + recvfrom_add_recvlen(pstate, recvlen); return recvlen; } @@ -200,9 +231,7 @@ static void recvfrom_newpktdata(FAR struct net_driver_s *dev, /* Update the accumulated size of the data read */ - pstate->rf_recvlen += recvlen; - pstate->rf_buffer += recvlen; - pstate->rf_buffer -= recvlen; + recvfrom_add_recvlen(pstate, recvlen); } #endif /* CONFIG_NET_PKT */ @@ -353,9 +382,7 @@ static inline void recvfrom_tcpreadahead(struct recvfrom_s *pstate) /* Update the accumulated size of the data read */ - pstate->rf_recvlen += recvlen; - pstate->rf_buffer += recvlen; - pstate->rf_buflen -= recvlen; + recvfrom_add_recvlen(pstate, recvlen); /* If we took all of the ata from the I/O buffer chain is empty, then * release it. If there is still data available in the I/O buffer @@ -1501,9 +1528,11 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* It is okay to block if we need to. If there is space to receive anything * more, then we will wait to receive the data. Otherwise return the number * of bytes read from the read-ahead buffer (already in 'ret'). + * + * NOTE: that recvfrom_udpreadahead() may set state.rf_recvlen == -1. */ - else if (state.rf_recvlen == 0) + else if (state.rf_recvlen <= 0) #endif { /* Get the device that will handle the packet transfers. This may be