Skip to content

Commit 25c0b52

Browse files
vicatcume-no-dev
authored andcommitted
Alternative Improve _uploadReadByte (#2656)
* add opportunity for more than one retry to _uploadReadByte * an alternative timeout-based method to making _uploadReadByte more resilient * move timing variables in the correct scope * implement and use client.getTimeout instead of hard-coded timeout in _uploadReadByte * add missing return * some refactoring to address respecting the timeout in a potentially deadlocked connection * fix spelling in comment * address review comments; move impl to cpp file for getTimeout, and remove local variable for currentMillis * remove redundant cast * need to check for timeout outside the inner while as well * update WebUpdate example to print something in unexpected callback condition * update log_e messages per review comments
1 parent e0beac8 commit 25c0b52

File tree

5 files changed

+47
-12
lines changed

5 files changed

+47
-12
lines changed

Diff for: cores/esp32/Stream.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ void Stream::setTimeout(unsigned long timeout) // sets the maximum number of mi
8282
{
8383
_timeout = timeout;
8484
}
85+
unsigned long Stream::getTimeout(void) {
86+
return _timeout;
87+
}
8588

8689
// find returns true if the target string is found
8790
bool Stream::find(const char *target)

Diff for: cores/esp32/Stream.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class Stream: public Print
5959
// parsing methods
6060

6161
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
62-
62+
unsigned long getTimeout(void);
6363
bool find(const char *target); // reads data from the stream until the target string is found
6464
bool find(uint8_t *target)
6565
{

Diff for: libraries/WebServer/examples/WebUpdate/WebUpdate.ino

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ void setup(void) {
5050
Update.printError(Serial);
5151
}
5252
Serial.setDebugOutput(false);
53+
} else {
54+
Serial.printf("Update Failed Unexpectedly (likely broken connection): status=%d\n", upload.status);
5355
}
5456
});
5557
server.begin();

Diff for: libraries/WebServer/src/Parsing.cpp

+34-4
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,41 @@ void WebServer::_uploadWriteByte(uint8_t b){
304304

305305
int WebServer::_uploadReadByte(WiFiClient& client){
306306
int res = client.read();
307-
if(res == -1){
308-
while(!client.available() && client.connected())
309-
delay(2);
310-
res = client.read();
307+
if(res < 0) {
308+
// keep trying until you either read a valid byte or timeout
309+
unsigned long startMillis = millis();
310+
long timeoutIntervalMillis = client.getTimeout();
311+
boolean timedOut = false;
312+
for(;;) {
313+
// loosely modeled after blinkWithoutDelay pattern
314+
while(!timedOut && !client.available() && client.connected()){
315+
delay(2);
316+
timedOut = millis() - startMillis >= timeoutIntervalMillis;
317+
}
318+
319+
res = client.read();
320+
if(res >= 0) {
321+
return res; // exit on a valid read
322+
}
323+
// NOTE: it is possible to get here and have all of the following
324+
// assertions hold true
325+
//
326+
// -- client.available() > 0
327+
// -- client.connected == true
328+
// -- res == -1
329+
//
330+
// a simple retry strategy overcomes this which is to say the
331+
// assertion is not permanent, but the reason that this works
332+
// is elusive, and possibly indicative of a more subtle underlying
333+
// issue
334+
335+
timedOut = millis() - startMillis >= timeoutIntervalMillis;
336+
if(timedOut) {
337+
return res; // exit on a timeout
338+
}
339+
}
311340
}
341+
312342
return res;
313343
}
314344

Diff for: libraries/WiFi/src/WiFiClient.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ int WiFiClient::setOption(int option, int *value)
279279
{
280280
int res = setsockopt(fd(), IPPROTO_TCP, option, (char *) value, sizeof(int));
281281
if(res < 0) {
282-
log_e("%d", errno);
282+
log_e("fail on fd %d, errno: %d, \"%s\"", fd(), errno, esp_err_to_name(errno));
283283
}
284284
return res;
285285
}
@@ -289,7 +289,7 @@ int WiFiClient::getOption(int option, int *value)
289289
size_t size = sizeof(int);
290290
int res = getsockopt(fd(), IPPROTO_TCP, option, (char *)value, &size);
291291
if(res < 0) {
292-
log_e("%d", errno);
292+
log_e("fail on fd %d, errno: %d, \"%s\"", fd(), errno, esp_err_to_name(errno));
293293
}
294294
return res;
295295
}
@@ -362,7 +362,7 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size)
362362
}
363363
}
364364
else if(res < 0) {
365-
log_e("%d", errno);
365+
log_e("fail on fd %d, errno: %d, \"%s\"", fd(), errno, esp_err_to_name(errno));
366366
if(errno != EAGAIN) {
367367
//if resource was busy, can try again, otherwise give up
368368
stop();
@@ -406,7 +406,7 @@ int WiFiClient::read(uint8_t *buf, size_t size)
406406
int res = -1;
407407
res = _rxBuffer->read(buf, size);
408408
if(_rxBuffer->failed()) {
409-
log_e("%d", errno);
409+
log_e("fail on fd %d, errno: %d, \"%s\"", fd(), errno, esp_err_to_name(errno));
410410
stop();
411411
}
412412
return res;
@@ -416,7 +416,7 @@ int WiFiClient::peek()
416416
{
417417
int res = _rxBuffer->peek();
418418
if(_rxBuffer->failed()) {
419-
log_e("%d", errno);
419+
log_e("fail on fd %d, errno: %d, \"%s\"", fd(), errno, esp_err_to_name(errno));
420420
stop();
421421
}
422422
return res;
@@ -430,7 +430,7 @@ int WiFiClient::available()
430430
}
431431
int res = _rxBuffer->available();
432432
if(_rxBuffer->failed()) {
433-
log_e("%d", errno);
433+
log_e("fail on fd %d, errno: %d, \"%s\"", fd(), errno, esp_err_to_name(errno));
434434
stop();
435435
}
436436
return res;
@@ -452,7 +452,7 @@ void WiFiClient::flush() {
452452
toRead = (a>WIFI_CLIENT_FLUSH_BUFFER_SIZE)?WIFI_CLIENT_FLUSH_BUFFER_SIZE:a;
453453
res = recv(fd(), buf, toRead, MSG_DONTWAIT);
454454
if(res < 0) {
455-
log_e("%d", errno);
455+
log_e("fail on fd %d, errno: %d, \"%s\"", fd(), errno, esp_err_to_name(errno));
456456
stop();
457457
break;
458458
}

0 commit comments

Comments
 (0)