mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-08-14 06:39:54 +00:00
fix(tcp): real task join in stop() + atomic _last_connect_attempt (greptile)
- stop() now waits on a _task_done flag the task sets right before exiting, instead of a fixed sleep. Closes a use-after-free window where an in-flight connect() overrunning CONNECT_TIMEOUT_MS (slow DNS) could touch `this` after ~TCPClientInterface() freed it. - _last_connect_attempt is now std::atomic<uint32_t> — it's read/written by task_loop() (core 0) and handle_disconnect() (core 1). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
988e42c52c
commit
7148859582
@@ -265,7 +265,9 @@ void TCPClientInterface::handle_disconnect() {
|
||||
|
||||
#ifdef ARDUINO
|
||||
/*static*/ void TCPClientInterface::tcp_task(void* arg) {
|
||||
static_cast<TCPClientInterface*>(arg)->task_loop();
|
||||
auto* self = static_cast<TCPClientInterface*>(arg);
|
||||
self->task_loop();
|
||||
self->_task_done = true; // let stop() join before the object is freed
|
||||
vTaskDelete(nullptr);
|
||||
}
|
||||
|
||||
@@ -299,11 +301,16 @@ void TCPClientInterface::task_loop() {
|
||||
|
||||
/*virtual*/ void TCPClientInterface::stop() {
|
||||
#ifdef ARDUINO
|
||||
// Stop the connect task first; wait long enough for any in-flight connect()
|
||||
// (bounded by CONNECT_TIMEOUT_MS) to finish so we don't close _client under it.
|
||||
// Join the task: signal it, then wait until it has actually left task_loop()
|
||||
// before tearing anything down. An in-flight connect() can overrun
|
||||
// CONNECT_TIMEOUT_MS on a slow DNS server, and ~TCPClientInterface() calls
|
||||
// stop() — returning early would risk a use-after-free on `this`.
|
||||
_task_running = false;
|
||||
if (_task_handle != nullptr) {
|
||||
vTaskDelay(pdMS_TO_TICKS(CONNECT_TIMEOUT_MS + 500));
|
||||
uint32_t deadline = millis() + CONNECT_TIMEOUT_MS + 2000;
|
||||
while (!_task_done && (int32_t)(millis() - deadline) < 0) {
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
}
|
||||
_task_handle = nullptr;
|
||||
}
|
||||
_conn_state.store(DISCONNECTED);
|
||||
|
||||
Reference in New Issue
Block a user