Adjust LWIP intf to avoid hangs/crashes under load (#1286)

It seems possible now for TCP connection _pcbs to disappear while being
processed, due to the new async context configuration.  This would cause
LWIP to panic when a NULL pcb was passed in.

Check for and avoid passing in null PCBs in the ClientContext.

Undo special-casing of sys_check_timeouts wrapper

AdvancedWebServer with heavy F5-refresh and #1274 test both pass.

Fixes #1274
This commit is contained in:
Earle F. Philhower, III 2023-03-08 11:48:23 -08:00 committed by GitHub
parent 54f9d3c414
commit e6c7b97b5e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 10 deletions

View file

@ -256,14 +256,10 @@ extern "C" {
} }
// sys_check_timeouts is special case because the async process will call it. If we're already in a timeout check, just do a noop // sys_check_timeouts is special case because the async process will call it. If we're already in a timeout check, just do a noop
auto_init_mutex(__sys_check_timeouts_mtx); extern void __real_sys_check_timeouts();
extern void __real_sys_check_timeouts(void);
void __wrap_sys_check_timeouts(void) { void __wrap_sys_check_timeouts(void) {
uint32_t owner; LWIPMutex m;
if (mutex_try_enter(&__sys_check_timeouts_mtx, &owner)) { __real_sys_check_timeouts();
__real_sys_check_timeouts();
mutex_exit(&__sys_check_timeouts_mtx);
}
} }
extern err_t __real_dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg); extern err_t __real_dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg);

View file

@ -328,7 +328,9 @@ public:
return false; return false;
} }
if (!_pcb) {
return false;
}
// force lwIP to send what can be sent // force lwIP to send what can be sent
tcp_output(_pcb); tcp_output(_pcb);
@ -522,6 +524,9 @@ protected:
const auto remaining = _datalen - _written; const auto remaining = _datalen - _written;
size_t next_chunk_size; size_t next_chunk_size;
{ {
if (!_pcb) {
return false;
}
next_chunk_size = std::min((size_t)tcp_sndbuf(_pcb), remaining); next_chunk_size = std::min((size_t)tcp_sndbuf(_pcb), remaining);
// Potentially reduce transmit size if we are tight on memory, but only if it doesn't return a 0 chunk size // Potentially reduce transmit size if we are tight on memory, but only if it doesn't return a 0 chunk size
if (next_chunk_size > (size_t)(1 << scale)) { if (next_chunk_size > (size_t)(1 << scale)) {
@ -550,6 +555,9 @@ protected:
flags |= TCP_WRITE_FLAG_COPY; flags |= TCP_WRITE_FLAG_COPY;
} }
if (!_pcb) {
return false;
}
err_t err = tcp_write(_pcb, buf, next_chunk_size, flags); err_t err = tcp_write(_pcb, buf, next_chunk_size, flags);
DEBUGV(":wrc %d %d %d\r\n", next_chunk_size, remaining, (int)err); DEBUGV(":wrc %d %d %d\r\n", next_chunk_size, remaining, (int)err);
@ -571,7 +579,7 @@ protected:
} }
} }
if (has_written) { if (has_written && _pcb) {
// lwIP's tcp_output doc: "Find out what we can send and send it" // lwIP's tcp_output doc: "Find out what we can send and send it"
// *with respect to Nagle* // *with respect to Nagle*
// more info: https://lists.gnu.org/archive/html/lwip-users/2017-11/msg00134.html // more info: https://lists.gnu.org/archive/html/lwip-users/2017-11/msg00134.html

View file

@ -3,7 +3,7 @@ version=1
author=Earle F. Philhower, III author=Earle F. Philhower, III
maintainer=Earle F. Philhower, III <earlephilhower@yahoo.com> maintainer=Earle F. Philhower, III <earlephilhower@yahoo.com>
sentence=RP2040 Cyw43XX wifi driver sentence=RP2040 Cyw43XX wifi driver
paragraph=Driver for the raspberry Pi Pico W wireless chip, CYW43439, to integrate witrh arduino-pico paragraph=Driver for the Raspberry Pi Pico W wireless chip, CYW43439, to integrate with arduino-pico
category=Communication category=Communication
url=https://github.com/earlephilhower/arduino-pico url=https://github.com/earlephilhower/arduino-pico
architectures=rp2040 architectures=rp2040