mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 23:18:10 +01:00
Fix scheduler with too many cancelled timers (#1309)
* Fix scheduler with too many cancelled timers * lint * use variable name
This commit is contained in:
parent
2c71ee7853
commit
b38b7019ea
2 changed files with 26 additions and 1 deletions
|
@ -8,6 +8,7 @@ namespace esphome {
|
|||
static const char *TAG = "scheduler";
|
||||
|
||||
static const uint32_t SCHEDULER_DONT_RUN = 4294967295UL;
|
||||
static const uint32_t MAX_LOGICALLY_DELETED_ITEMS = 10;
|
||||
|
||||
// Uncomment to debug scheduler
|
||||
// #define ESPHOME_DEBUG_SCHEDULER
|
||||
|
@ -107,6 +108,26 @@ void ICACHE_RAM_ATTR HOT Scheduler::call() {
|
|||
}
|
||||
#endif // ESPHOME_DEBUG_SCHEDULER
|
||||
|
||||
auto to_remove_was = to_remove_;
|
||||
auto items_was = items_.size();
|
||||
// If we have too many items to remove
|
||||
if (to_remove_ > MAX_LOGICALLY_DELETED_ITEMS) {
|
||||
std::vector<std::unique_ptr<SchedulerItem>> valid_items;
|
||||
while (!this->empty_()) {
|
||||
auto item = std::move(this->items_[0]);
|
||||
this->pop_raw_();
|
||||
valid_items.push_back(std::move(item));
|
||||
}
|
||||
this->items_ = std::move(valid_items);
|
||||
|
||||
// The following should not happen unless I'm missing something
|
||||
if (to_remove_ != 0) {
|
||||
ESP_LOGW(TAG, "to_remove_ was %u now: %u items where %zu now %zu. Please report this", to_remove_was, to_remove_,
|
||||
items_was, items_.size());
|
||||
to_remove_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (!this->empty_()) {
|
||||
// use scoping to indicate visibility of `item` variable
|
||||
{
|
||||
|
@ -147,6 +168,7 @@ void ICACHE_RAM_ATTR HOT Scheduler::call() {
|
|||
|
||||
if (item->remove) {
|
||||
// We were removed/cancelled in the function call, stop
|
||||
to_remove_--;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -182,6 +204,7 @@ void HOT Scheduler::cleanup_() {
|
|||
if (!item->remove)
|
||||
return;
|
||||
|
||||
to_remove_--;
|
||||
this->pop_raw_();
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +216,8 @@ void HOT Scheduler::push_(std::unique_ptr<Scheduler::SchedulerItem> item) { this
|
|||
bool HOT Scheduler::cancel_item_(Component *component, const std::string &name, Scheduler::SchedulerItem::Type type) {
|
||||
bool ret = false;
|
||||
for (auto &it : this->items_)
|
||||
if (it->component == component && it->name == name && it->type == type) {
|
||||
if (it->component == component && it->name == name && it->type == type && !it->remove) {
|
||||
to_remove_++;
|
||||
it->remove = true;
|
||||
ret = true;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ class Scheduler {
|
|||
std::vector<std::unique_ptr<SchedulerItem>> to_add_;
|
||||
uint32_t last_millis_{0};
|
||||
uint8_t millis_major_{0};
|
||||
uint32_t to_remove_{0};
|
||||
};
|
||||
|
||||
} // namespace esphome
|
||||
|
|
Loading…
Reference in a new issue