fix: only touch the task watchdog from tasks that are subscribed to it

Only loop() is subscribed.  setConnected() runs on the WiFi event task
and reached SocketEmitter::endEmit(), whose plain esp_task_wdt_reset()
logged "esp_task_wdt_reset(707): task not found" on every boot.  The web
and socket handlers on async_tcp did the same.

/scanaps on async_tcp called esp_task_wdt_add(NULL) after the scan,
subscribing a task that nothing resets, so the board could panic 15 s
after a scan from the UI.

TaskWdt.h resets only a subscribed task and re-adds a task after a long
call only when it was watched before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-21 13:45:04 +02:00
parent e9109c56e0
commit 609cd455c6
10 changed files with 154 additions and 57 deletions

21
src/TaskWdt.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef TASK_WDT_H
#define TASK_WDT_H
#include <esp_task_wdt.h>
// Task watchdog calls that are safe from any task.
//
// Only loop() is subscribed to the watchdog. Code it shares with other tasks
// is not: the WiFi event task runs ESPNetwork::setConnected() and async_tcp
// runs the web and socket handlers. A plain esp_task_wdt_reset() there logs
// "esp_task_wdt_reset(707): task not found", and an esp_task_wdt_add() there
// subscribes a task that nothing resets, so it panics once the timeout runs out.
// Resets the watchdog if the calling task is subscribed to it.
inline void resetTaskWdt() {
if(esp_task_wdt_status(NULL) == ESP_OK) esp_task_wdt_reset();
}
// Stops watching the calling task around a call that blocks past the timeout.
// True when it was watched, so resumeTaskWdt() knows to add it back.
inline bool pauseTaskWdt() { return esp_task_wdt_delete(NULL) == ESP_OK; }
inline void resumeTaskWdt(bool paused) { if(paused) esp_task_wdt_add(NULL); }
#endif