mirror of
https://github.com/esphome/esphome.git
synced 2026-05-28 04:55:48 +08:00
[core] Scheduler: don't sleep while defer queue is non-empty (#15968)
This commit is contained in:
@@ -414,8 +414,27 @@ bool HOT Scheduler::cancel_retry(Component *component, uint32_t id) {
|
|||||||
|
|
||||||
optional<uint32_t> HOT Scheduler::next_schedule_in(uint32_t now) {
|
optional<uint32_t> HOT Scheduler::next_schedule_in(uint32_t now) {
|
||||||
// IMPORTANT: This method should only be called from the main thread (loop task).
|
// IMPORTANT: This method should only be called from the main thread (loop task).
|
||||||
// It performs cleanup and accesses items_[0] without holding a lock, which is only
|
// Accesses items_[0] and the fast-path empty checks without holding a lock, which
|
||||||
// safe when called from the main thread. Other threads must not call this method.
|
// is only safe from the main thread. Other threads must not call this method.
|
||||||
|
//
|
||||||
|
// Note: cleanup_() is only invoked on the items_[0] path below. The early returns
|
||||||
|
// skip it because they don't read items_[0], and Scheduler::call() at the top of
|
||||||
|
// every loop iteration already performs its own cleanup before the next sleep-
|
||||||
|
// duration computation happens.
|
||||||
|
|
||||||
|
#ifndef ESPHOME_THREAD_SINGLE
|
||||||
|
// defer() items live in a separate queue that is drained at the top of every
|
||||||
|
// loop tick via process_defer_queue_(). If any are pending, the next loop
|
||||||
|
// iteration has work to do right now -- don't let the caller sleep.
|
||||||
|
if (!this->defer_empty_())
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
// On single-threaded builds, defer() routes through set_timeout(..., 0) which
|
||||||
|
// stages in to_add_. process_to_add() runs at the top of every scheduler.call(),
|
||||||
|
// so anything in to_add_ becomes runnable on the next iteration; don't sleep.
|
||||||
|
if (!this->to_add_empty_())
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
// If no items, return empty optional
|
// If no items, return empty optional
|
||||||
if (!this->cleanup_())
|
if (!this->cleanup_())
|
||||||
|
|||||||
Reference in New Issue
Block a user