From 4e17d14acca044d452b0ec0516659a47c907b121 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 14 Sep 2025 17:05:56 -0500 Subject: [PATCH] [scheduler] Fix timing accumulation in scheduler causing incorrect execution measurements (#10719) --- esphome/core/scheduler.cpp | 8 ++++---- esphome/core/scheduler.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/core/scheduler.cpp b/esphome/core/scheduler.cpp index 68da0a56ca..71e2a00fbe 100644 --- a/esphome/core/scheduler.cpp +++ b/esphome/core/scheduler.cpp @@ -345,7 +345,7 @@ void HOT Scheduler::call(uint32_t now) { // Execute callback without holding lock to prevent deadlocks // if the callback tries to call defer() again if (!this->should_skip_item_(item.get())) { - this->execute_item_(item.get(), now); + now = this->execute_item_(item.get(), now); } // Recycle the defer item after execution this->recycle_item_(std::move(item)); @@ -483,7 +483,7 @@ void HOT Scheduler::call(uint32_t now) { // Warning: During callback(), a lot of stuff can happen, including: // - timeouts/intervals get added, potentially invalidating vector pointers // - timeouts/intervals get cancelled - this->execute_item_(item.get(), now); + now = this->execute_item_(item.get(), now); LockGuard guard{this->lock_}; @@ -568,11 +568,11 @@ void HOT Scheduler::pop_raw_() { } // Helper to execute a scheduler item -void HOT Scheduler::execute_item_(SchedulerItem *item, uint32_t now) { +uint32_t HOT Scheduler::execute_item_(SchedulerItem *item, uint32_t now) { App.set_current_component(item->component); WarnIfComponentBlockingGuard guard{item->component, now}; item->callback(); - guard.finish(); + return guard.finish(); } // Common implementation for cancel operations diff --git a/esphome/core/scheduler.h b/esphome/core/scheduler.h index 301342e8c2..885ee13754 100644 --- a/esphome/core/scheduler.h +++ b/esphome/core/scheduler.h @@ -254,7 +254,7 @@ class Scheduler { } // Helper to execute a scheduler item - void execute_item_(SchedulerItem *item, uint32_t now); + uint32_t execute_item_(SchedulerItem *item, uint32_t now); // Helper to check if item should be skipped bool should_skip_item_(SchedulerItem *item) const {