[web_server] Fix ESP8266 watchdog panic by deferring actions to main loop

This commit is contained in:
J. Nick Koston
2026-02-04 21:14:25 +01:00
parent 4a579700a0
commit 1b90ccde27
2 changed files with 6 additions and 20 deletions

View File

@@ -721,11 +721,7 @@ void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlM
}
if (action != SWITCH_ACTION_NONE) {
#ifdef USE_ESP8266
execute_switch_action(obj, action);
#else
this->defer([obj, action]() { execute_switch_action(obj, action); });
#endif
request->send(200);
} else {
request->send(404);
@@ -1645,11 +1641,7 @@ void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMat
}
if (action != LOCK_ACTION_NONE) {
#ifdef USE_ESP8266
execute_lock_action(obj, action);
#else
this->defer([obj, action]() { execute_lock_action(obj, action); });
#endif
request->send(200);
} else {
request->send(404);
@@ -2015,19 +2007,14 @@ void WebServer::handle_infrared_request(AsyncWebServerRequest *request, const Ur
return;
}
#ifdef USE_ESP8266
// ESP8266 is single-threaded, call directly
call.set_raw_timings_base64url(encoded);
call.perform();
#else
// Defer to main loop for thread safety. Move encoded string into lambda to ensure
// it outlives the call - set_raw_timings_base64url stores a pointer, so the string
// must remain valid until perform() completes.
// ESP8266 also needs this because ESPAsyncWebServer callbacks run in "sys" context.
this->defer([call, encoded = std::move(encoded)]() mutable {
call.set_raw_timings_base64url(encoded);
call.perform();
});
#endif
request->send(200);
return;

View File

@@ -42,13 +42,12 @@ using ParamNameType = const __FlashStringHelper *;
using ParamNameType = const char *;
#endif
// ESP8266 is single-threaded, so actions can execute directly in request context.
// Multi-core platforms need to defer to main loop thread for thread safety.
#ifdef USE_ESP8266
#define DEFER_ACTION(capture, action) action
#else
// All platforms need to defer actions to main loop thread.
// Multi-core platforms need this for thread safety.
// ESP8266 needs this because ESPAsyncWebServer callbacks run in "sys" context
// (SDK system context), not "cont" context (continuation/main loop). Calling
// yield() from sys context causes a panic in the Arduino core.
#define DEFER_ACTION(capture, action) this->defer([capture]() mutable { action; })
#endif
/// Result of matching a URL against an entity
struct EntityMatchResult {