mirror of
https://github.com/esphome/esphome.git
synced 2026-02-08 00:31:58 +00:00
[web_server] Fix ESP8266 watchdog panic by deferring actions to main loop (#13765)
This commit is contained in:
@@ -721,11 +721,7 @@ void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlM
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action != SWITCH_ACTION_NONE) {
|
if (action != SWITCH_ACTION_NONE) {
|
||||||
#ifdef USE_ESP8266
|
|
||||||
execute_switch_action(obj, action);
|
|
||||||
#else
|
|
||||||
this->defer([obj, action]() { execute_switch_action(obj, action); });
|
this->defer([obj, action]() { execute_switch_action(obj, action); });
|
||||||
#endif
|
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else {
|
} else {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
@@ -1645,11 +1641,7 @@ void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMat
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action != LOCK_ACTION_NONE) {
|
if (action != LOCK_ACTION_NONE) {
|
||||||
#ifdef USE_ESP8266
|
|
||||||
execute_lock_action(obj, action);
|
|
||||||
#else
|
|
||||||
this->defer([obj, action]() { execute_lock_action(obj, action); });
|
this->defer([obj, action]() { execute_lock_action(obj, action); });
|
||||||
#endif
|
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else {
|
} else {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
@@ -2015,19 +2007,14 @@ void WebServer::handle_infrared_request(AsyncWebServerRequest *request, const Ur
|
|||||||
return;
|
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
|
// 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
|
// it outlives the call - set_raw_timings_base64url stores a pointer, so the string
|
||||||
// must remain valid until perform() completes.
|
// 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 {
|
this->defer([call, encoded = std::move(encoded)]() mutable {
|
||||||
call.set_raw_timings_base64url(encoded);
|
call.set_raw_timings_base64url(encoded);
|
||||||
call.perform();
|
call.perform();
|
||||||
});
|
});
|
||||||
#endif
|
|
||||||
|
|
||||||
request->send(200);
|
request->send(200);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -42,13 +42,12 @@ using ParamNameType = const __FlashStringHelper *;
|
|||||||
using ParamNameType = const char *;
|
using ParamNameType = const char *;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ESP8266 is single-threaded, so actions can execute directly in request context.
|
// All platforms need to defer actions to main loop thread.
|
||||||
// Multi-core platforms need to defer to main loop thread for thread safety.
|
// Multi-core platforms need this for thread safety.
|
||||||
#ifdef USE_ESP8266
|
// ESP8266 needs this because ESPAsyncWebServer callbacks run in "sys" context
|
||||||
#define DEFER_ACTION(capture, action) action
|
// (SDK system context), not "cont" context (continuation/main loop). Calling
|
||||||
#else
|
// yield() from sys context causes a panic in the Arduino core.
|
||||||
#define DEFER_ACTION(capture, action) this->defer([capture]() mutable { action; })
|
#define DEFER_ACTION(capture, action) this->defer([capture]() mutable { action; })
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Result of matching a URL against an entity
|
/// Result of matching a URL against an entity
|
||||||
struct EntityMatchResult {
|
struct EntityMatchResult {
|
||||||
|
|||||||
Reference in New Issue
Block a user