From 2895bb8b84daf68e3cc7d0762a59e1c87fb5bb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 7 Sep 2021 14:06:12 -0500 Subject: [PATCH] Check for readable socket right before signaling a read timeout In the current architecture, all socket reads proceed before all socket polls, and the socket poll is where the read timeout check is made. If the sum of the execution time of all write and read handlers exceeds that of the next timeout-enabled polled socket, the code would incorrectly close due to a "timeout", even if some readable data became available in the meantime. Fix by checking (via select()) one last time and resetting the timer if the socket has some readable data. --- src/AsyncTCP.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/AsyncTCP.cpp b/src/AsyncTCP.cpp index 61bd4b5..f106e2a 100644 --- a/src/AsyncTCP.cpp +++ b/src/AsyncTCP.cpp @@ -745,6 +745,20 @@ void AsyncClient::_sockPoll(void) } xSemaphoreGive(_write_mutex); + // RX Timeout? Check for readable socket before bailing out + if (_rx_since_timeout && (now - _rx_last_packet) >= (_rx_since_timeout * 1000)) { + fd_set sockSet_r; + struct timeval tv; + + FD_ZERO(&sockSet_r); + FD_SET(_socket, &sockSet_r); + tv.tv_sec = 0; + tv.tv_usec = 0; + + int r = select(_socket + 1, &sockSet_r, NULL, NULL, &tv); + if (r > 0) _rx_last_packet = now; + } + // RX Timeout if (_rx_since_timeout && (now - _rx_last_packet) >= (_rx_since_timeout * 1000)) { //log_w("rx timeout %d", pcb->state);