mirror of
https://github.com/esphome/esphome.git
synced 2026-09-13 16:18:41 +00:00
[core] wakeable_delay: yield on already-woken fast path (ESP8266, RP2040)
When `g_main_loop_woke` is already set on entry to `wakeable_delay()`, both the ESP8266 and RP2040 paths consume the flag and return without yielding. That's safe in isolation, but if a caller loops on `wakeable_delay()` (e.g. `LWIPRawImpl::wait_for_data_()` waiting for SO_RCVTIMEO), and ISR sources (GPIO, timer, WiFi RX on ESP8266; alarm / async on RP2040) keep re-setting the flag between iterations, every iteration takes the fast path and the loop never yields. That can starve the SDK / async context, blocking actual TCP delivery to our socket and causing OTA reads to time out on busy devices even though there is data in flight. The PR that introduced `wait_for_data_()` (#14675) relied on `wakeable_delay()` to yield on every iteration; this restores that property on the fast path. Adds `delay(0)` on ESP8266 and `yield()` on RP2040 to the fast path, matching the yield behaviour those platforms already use for the `ms == 0` poll case.
This commit is contained in:
@@ -36,6 +36,10 @@ inline void ESPHOME_ALWAYS_INLINE wakeable_delay(uint32_t ms) {
|
||||
}
|
||||
if (g_main_loop_woke) {
|
||||
g_main_loop_woke = false;
|
||||
// Yield even on the already-woken fast path so callers in tight loops
|
||||
// (e.g. lwIP raw TCP wait_for_data_) make forward progress when ISRs
|
||||
// keep re-setting g_main_loop_woke between iterations.
|
||||
delay(0);
|
||||
return;
|
||||
}
|
||||
esp_delay(ms, []() { return !g_main_loop_woke; });
|
||||
|
||||
@@ -36,6 +36,10 @@ void wakeable_delay(uint32_t ms) {
|
||||
}
|
||||
if (g_main_loop_woke) {
|
||||
g_main_loop_woke = false;
|
||||
// Yield even on the already-woken fast path so callers in tight loops
|
||||
// (e.g. lwIP raw TCP wait_for_data_) make forward progress when async
|
||||
// wakes keep re-setting g_main_loop_woke between iterations.
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
s_delay_expired = false;
|
||||
|
||||
Reference in New Issue
Block a user