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:
parent
83a8076db8
commit
d0171574d8
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user