From 932d0a5d8b9d00e2f917d1e14ca20fe9b1c6493b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 6 Jul 2025 19:50:54 -0500 Subject: [PATCH] fix another race --- esphome/core/scheduler.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/esphome/core/scheduler.cpp b/esphome/core/scheduler.cpp index 073eeb4a45..64b44a3153 100644 --- a/esphome/core/scheduler.cpp +++ b/esphome/core/scheduler.cpp @@ -392,11 +392,13 @@ void HOT Scheduler::cleanup_() { return; // We must hold the lock for the entire cleanup operation because: - // 1. We're modifying items_ (via pop_raw_) which other threads may be reading/writing - // 2. We're decrementing to_remove_ which must be synchronized with increments - // 3. We need a consistent view of items_ throughout the iteration - // 4. Other threads might be adding items or modifying the heap structure - // Without the lock, we could have race conditions leading to crashes or corruption + // 1. We're modifying items_ (via pop_raw_) which requires exclusive access + // 2. We're decrementing to_remove_ which is also modified by other threads + // (though all modifications are already under lock) + // 3. Other threads read items_ when searching for items to cancel in cancel_item_locked_() + // 4. We need a consistent view of items_ and to_remove_ throughout the operation + // Without the lock, we could access items_ while another thread is reading it, + // leading to race conditions LockGuard guard{this->lock_}; while (!this->items_.empty()) { auto &item = this->items_[0];