mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 15:08: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
c9caf44c2e
commit
b266fb37a3
2 changed files with 26 additions and 1 deletions
|
@ -8,6 +8,7 @@ namespace esphome {
|
||||||
static const char *TAG = "scheduler";
|
static const char *TAG = "scheduler";
|
||||||
|
|
||||||
static const uint32_t SCHEDULER_DONT_RUN = 4294967295UL;
|
static const uint32_t SCHEDULER_DONT_RUN = 4294967295UL;
|
||||||
|
static const uint32_t MAX_LOGICALLY_DELETED_ITEMS = 10;
|
||||||
|
|
||||||
// Uncomment to debug scheduler
|
// Uncomment to debug scheduler
|
||||||
// #define ESPHOME_DEBUG_SCHEDULER
|
// #define ESPHOME_DEBUG_SCHEDULER
|
||||||
|
@ -107,6 +108,26 @@ void ICACHE_RAM_ATTR HOT Scheduler::call() {
|
||||||
}
|
}
|
||||||
#endif // ESPHOME_DEBUG_SCHEDULER
|
#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_()) {
|
while (!this->empty_()) {
|
||||||
// use scoping to indicate visibility of `item` variable
|
// use scoping to indicate visibility of `item` variable
|
||||||
{
|
{
|
||||||
|
@ -147,6 +168,7 @@ void ICACHE_RAM_ATTR HOT Scheduler::call() {
|
||||||
|
|
||||||
if (item->remove) {
|
if (item->remove) {
|
||||||
// We were removed/cancelled in the function call, stop
|
// We were removed/cancelled in the function call, stop
|
||||||
|
to_remove_--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +204,7 @@ void HOT Scheduler::cleanup_() {
|
||||||
if (!item->remove)
|
if (!item->remove)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
to_remove_--;
|
||||||
this->pop_raw_();
|
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 HOT Scheduler::cancel_item_(Component *component, const std::string &name, Scheduler::SchedulerItem::Type type) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
for (auto &it : this->items_)
|
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;
|
it->remove = true;
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ class Scheduler {
|
||||||
std::vector<std::unique_ptr<SchedulerItem>> to_add_;
|
std::vector<std::unique_ptr<SchedulerItem>> to_add_;
|
||||||
uint32_t last_millis_{0};
|
uint32_t last_millis_{0};
|
||||||
uint8_t millis_major_{0};
|
uint8_t millis_major_{0};
|
||||||
|
uint32_t to_remove_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
Loading…
Reference in a new issue