mirror of
https://github.com/esphome/esphome.git
synced 2025-10-08 04:43:46 +01:00
[scheduler] Deduplicate item removal code with template helper (#11017)
This commit is contained in:
@@ -118,7 +118,6 @@ void HOT Scheduler::set_timer_common_(Component *component, SchedulerItem::Type
|
|||||||
item->type = type;
|
item->type = type;
|
||||||
item->callback = std::move(func);
|
item->callback = std::move(func);
|
||||||
// Initialize remove to false (though it should already be from constructor)
|
// Initialize remove to false (though it should already be from constructor)
|
||||||
// Not using mark_item_removed_ helper since we're setting to false, not true
|
|
||||||
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
||||||
item->remove.store(false, std::memory_order_relaxed);
|
item->remove.store(false, std::memory_order_relaxed);
|
||||||
#else
|
#else
|
||||||
@@ -600,12 +599,7 @@ bool HOT Scheduler::cancel_item_locked_(Component *component, const char *name_c
|
|||||||
#ifndef ESPHOME_THREAD_SINGLE
|
#ifndef ESPHOME_THREAD_SINGLE
|
||||||
// Mark items in defer queue as cancelled (they'll be skipped when processed)
|
// Mark items in defer queue as cancelled (they'll be skipped when processed)
|
||||||
if (type == SchedulerItem::TIMEOUT) {
|
if (type == SchedulerItem::TIMEOUT) {
|
||||||
for (auto &item : this->defer_queue_) {
|
total_cancelled += this->mark_matching_items_removed_(this->defer_queue_, component, name_cstr, type, match_retry);
|
||||||
if (this->matches_item_(item, component, name_cstr, type, match_retry)) {
|
|
||||||
this->mark_item_removed_(item.get());
|
|
||||||
total_cancelled++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif /* not ESPHOME_THREAD_SINGLE */
|
#endif /* not ESPHOME_THREAD_SINGLE */
|
||||||
|
|
||||||
@@ -620,23 +614,13 @@ bool HOT Scheduler::cancel_item_locked_(Component *component, const char *name_c
|
|||||||
total_cancelled++;
|
total_cancelled++;
|
||||||
}
|
}
|
||||||
// For other items in heap, we can only mark for removal (can't remove from middle of heap)
|
// For other items in heap, we can only mark for removal (can't remove from middle of heap)
|
||||||
for (auto &item : this->items_) {
|
size_t heap_cancelled = this->mark_matching_items_removed_(this->items_, component, name_cstr, type, match_retry);
|
||||||
if (this->matches_item_(item, component, name_cstr, type, match_retry)) {
|
total_cancelled += heap_cancelled;
|
||||||
this->mark_item_removed_(item.get());
|
this->to_remove_ += heap_cancelled; // Track removals for heap items
|
||||||
total_cancelled++;
|
|
||||||
this->to_remove_++; // Track removals for heap items
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel items in to_add_
|
// Cancel items in to_add_
|
||||||
for (auto &item : this->to_add_) {
|
total_cancelled += this->mark_matching_items_removed_(this->to_add_, component, name_cstr, type, match_retry);
|
||||||
if (this->matches_item_(item, component, name_cstr, type, match_retry)) {
|
|
||||||
this->mark_item_removed_(item.get());
|
|
||||||
total_cancelled++;
|
|
||||||
// Don't track removals for to_add_ items
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return total_cancelled > 0;
|
return total_cancelled > 0;
|
||||||
}
|
}
|
||||||
|
@@ -280,19 +280,30 @@ class Scheduler {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to mark item for removal (platform-specific)
|
// Helper to mark matching items in a container as removed
|
||||||
|
// Returns the number of items marked for removal
|
||||||
// For ESPHOME_THREAD_MULTI_NO_ATOMICS platforms, the caller must hold the scheduler lock before calling this
|
// For ESPHOME_THREAD_MULTI_NO_ATOMICS platforms, the caller must hold the scheduler lock before calling this
|
||||||
// function.
|
// function.
|
||||||
void mark_item_removed_(SchedulerItem *item) {
|
template<typename Container>
|
||||||
|
size_t mark_matching_items_removed_(Container &container, Component *component, const char *name_cstr,
|
||||||
|
SchedulerItem::Type type, bool match_retry) {
|
||||||
|
size_t count = 0;
|
||||||
|
for (auto &item : container) {
|
||||||
|
if (this->matches_item_(item, component, name_cstr, type, match_retry)) {
|
||||||
|
// Mark item for removal (platform-specific)
|
||||||
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
||||||
// Multi-threaded with atomics: use atomic store
|
// Multi-threaded with atomics: use atomic store
|
||||||
item->remove.store(true, std::memory_order_release);
|
item->remove.store(true, std::memory_order_release);
|
||||||
#else
|
#else
|
||||||
// Single-threaded (ESPHOME_THREAD_SINGLE) or
|
// Single-threaded (ESPHOME_THREAD_SINGLE) or
|
||||||
// multi-threaded without atomics (ESPHOME_THREAD_MULTI_NO_ATOMICS): direct write
|
// multi-threaded without atomics (ESPHOME_THREAD_MULTI_NO_ATOMICS): direct write
|
||||||
// For ESPHOME_THREAD_MULTI_NO_ATOMICS, caller MUST hold lock!
|
// For ESPHOME_THREAD_MULTI_NO_ATOMICS, caller MUST hold lock!
|
||||||
item->remove = true;
|
item->remove = true;
|
||||||
#endif
|
#endif
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Template helper to check if any item in a container matches our criteria
|
// Template helper to check if any item in a container matches our criteria
|
||||||
|
Reference in New Issue
Block a user