1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Fix TCP race condition, remove fixed delay in CC (#5167)

ClientContext::_wait_for_sent() could dereference a TCP's _pcb after
the connection was dropped by the OS, resulting in a crash.

Move the connection dropped check to catch this case, and replace
a fixed millisecond delay() with a yield and timeout value to minimize
wasted time when transmission completes.
This commit is contained in:
Earle F. Philhower, III 2018-09-26 08:47:10 -07:00 committed by GitHub
parent 83a8076db8
commit d0171574d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -308,13 +308,19 @@ public:
if (!_pcb)
return true;
int loop = -1;
int prevsndbuf = -1;
max_wait_ms++;
// wait for peer's acks to flush lwIP's output buffer
uint32_t last_sent = millis();
while (1) {
if (millis() - last_sent > (uint32_t) max_wait_ms) {
#ifdef DEBUGV
// wait until sent: timeout
DEBUGV(":wustmo\n");
#endif
// All data was not flushed, timeout hit
return false;
}
// force lwIP to send what can be sent
tcp_output(_pcb);
@ -322,25 +328,20 @@ public:
int sndbuf = tcp_sndbuf(_pcb);
if (sndbuf != prevsndbuf) {
// send buffer has changed (or first iteration)
// we received an ack: restart the loop counter
prevsndbuf = sndbuf;
loop = max_wait_ms;
// We just sent a bit, move timeout forward
last_sent = millis();
}
if (state() != ESTABLISHED || sndbuf == TCP_SND_BUF || --loop <= 0)
yield();
if ((state() != ESTABLISHED) || (sndbuf == TCP_SND_BUF)) {
break;
delay(1);
}
}
#ifdef DEBUGV
if (loop <= 0) {
// wait until sent: timeout
DEBUGV(":wustmo\n");
}
#endif
return max_wait_ms > 0;
// All data flushed
return true;
}
uint8_t state() const