Web: fix crash/deadlock when disabling web panel via HTTP command
Calling `set web off` through the web panel caused the device to either hang permanently or crash with a Guru Meditation Error (LoadProhibited). Root cause: the HTTP command handler runs inside the httpd task and synchronously called `setWebEnabled(false)`, which called `_panel.stop()` -> `httpd_ssl_stop()` on the very connection that was serving the request. This is unsafe in two ways: 1. `httpd_ssl_stop()` blocks waiting for the httpd task to finish, but the httpd task is the one executing the handler — a self-deadlock. 2. Even if the stop proceeds, closing the active TLS connection from within its own handler triggers lwIP teardown (esp_netif_down_api -> dhcp_stop -> TCP RST) while the WiFi driver is in an inconsistent state, causing a null-pointer dereference in ieee80211_output_do. The deadlock was further compounded by a second concurrent call: while the httpd task was stuck in httpd_ssl_stop(), the main loop kept running, called ensureWebServer(), saw _server != nullptr (never cleared because httpd_ssl_stop() never returned), and issued a second httpd_ssl_stop() on the same handle — blocking the main loop as well and stopping all radio packet processing until reboot. The explicit start/stop calls in setWebEnabled() were redundant: WebService::loop() already calls ensureWebServer() on every iteration, which starts the server when enabled and WiFi is up, and stops it otherwise. Remove the block entirely and let loop() handle both transitions safely from the main loop context, outside the httpd task.
Этот коммит содержится в:
@@ -56,15 +56,7 @@ bool WebService::setWebEnabled(bool enabled) {
|
||||
if (!enabled) {
|
||||
_suspended_for_ota = false;
|
||||
}
|
||||
bool ok = savePrefs();
|
||||
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
||||
if (_prefs.web_enabled != 0 && !_suspended_for_ota) {
|
||||
ensureWebServer();
|
||||
} else {
|
||||
_panel.stop();
|
||||
}
|
||||
#endif
|
||||
return ok;
|
||||
return savePrefs();
|
||||
}
|
||||
|
||||
bool WebService::setWebStatsEnabled(bool enabled) {
|
||||
|
||||
Ссылка в новой задаче
Block a user