8#ifdef ESPHOME_THREAD_MULTI_ATOMICS
25 friend void ::esphome::retry_handler(
const std::shared_ptr<RetryArgs> &args);
29 void set_timeout(Component *component,
const std::string &name, uint32_t timeout, std::function<
void()> func);
41 void set_timeout(Component *component,
const char *name, uint32_t timeout, std::function<
void()> func);
43 bool cancel_timeout(Component *component,
const std::string &name);
44 bool cancel_timeout(Component *component,
const char *name);
46 void set_interval(Component *component,
const std::string &name, uint32_t interval, std::function<
void()> func);
58 void set_interval(Component *component,
const char *name, uint32_t interval, std::function<
void()> func);
60 bool cancel_interval(Component *component,
const std::string &name);
61 bool cancel_interval(Component *component,
const char *name);
62 void set_retry(Component *component,
const std::string &name, uint32_t initial_wait_time, uint8_t max_attempts,
63 std::function<
RetryResult(uint8_t)> func,
float backoff_increase_factor = 1.0f);
64 void set_retry(Component *component,
const char *name, uint32_t initial_wait_time, uint8_t max_attempts,
65 std::function<
RetryResult(uint8_t)> func,
float backoff_increase_factor = 1.0f);
66 bool cancel_retry(Component *component,
const std::string &name);
67 bool cancel_retry(Component *component,
const char *name);
74 optional<uint32_t> next_schedule_in(uint32_t now);
78 void call(uint32_t now);
80 void process_to_add();
83 struct SchedulerItem {
90 uint64_t next_execution_;
94 const char *static_name;
98 std::function<void()> callback;
100#ifdef ESPHOME_THREAD_MULTI_ATOMICS
103 std::atomic<bool> remove{
false};
106 enum Type : uint8_t {
TIMEOUT, INTERVAL }
type : 1;
107 bool name_is_dynamic : 1;
113 enum Type : uint8_t {
TIMEOUT, INTERVAL }
type : 1;
115 bool name_is_dynamic : 1;
122 : component(nullptr),
125#ifdef ESPHOME_THREAD_MULTI_ATOMICS
128 name_is_dynamic(false),
133 name_is_dynamic(
false),
136 name_.static_name =
nullptr;
141 if (name_is_dynamic) {
142 delete[] name_.dynamic_name;
147 SchedulerItem(
const SchedulerItem &) =
delete;
148 SchedulerItem &operator=(
const SchedulerItem &) =
delete;
151 SchedulerItem(SchedulerItem &&) =
delete;
152 SchedulerItem &operator=(SchedulerItem &&) =
delete;
155 const char *get_name()
const {
return name_is_dynamic ? name_.dynamic_name : name_.static_name; }
158 void set_name(
const char *name,
bool make_copy =
false) {
160 if (name_is_dynamic && name_.dynamic_name) {
161 delete[] name_.dynamic_name;
162 name_is_dynamic =
false;
167 name_.static_name =
nullptr;
168 }
else if (make_copy) {
170 size_t len = strlen(name);
171 name_.dynamic_name =
new char[
len + 1];
172 memcpy(name_.dynamic_name, name,
len + 1);
173 name_is_dynamic =
true;
176 name_.static_name = name;
180 static bool cmp(
const std::unique_ptr<SchedulerItem> &a,
const std::unique_ptr<SchedulerItem> &b);
181 const char *get_type_str()
const {
return (
type == TIMEOUT) ?
"timeout" :
"interval"; }
182 const char *get_source()
const {
return component ? component->get_component_source() :
"unknown"; }
186 void set_timer_common_(Component *component, SchedulerItem::Type
type,
bool is_static_string,
const void *name_ptr,
187 uint32_t delay, std::function<
void()> func,
bool is_retry =
false);
190 void set_retry_common_(Component *component,
bool is_static_string,
const void *name_ptr, uint32_t initial_wait_time,
191 uint8_t max_attempts, std::function<
RetryResult(uint8_t)> func,
float backoff_increase_factor);
193 uint64_t millis_64_(uint32_t now);
202 bool cancel_item_locked_(Component *component,
const char *name, SchedulerItem::Type
type,
bool match_retry =
false);
205 inline const char *get_name_cstr_(
bool is_static_string,
const void *name_ptr) {
206 return is_static_string ?
static_cast<const char *
>(name_ptr) : static_cast<const std::string *>(name_ptr)->c_str();
210 bool cancel_item_(Component *component,
bool is_static_string,
const void *name_ptr, SchedulerItem::Type
type);
213 inline bool HOT matches_item_(
const std::unique_ptr<SchedulerItem> &item, Component *component,
const char *name_cstr,
214 SchedulerItem::Type
type,
bool match_retry,
bool skip_removed =
true)
const {
215 if (item->component != component || item->type !=
type || (skip_removed && item->remove) ||
216 (match_retry && !item->is_retry)) {
219 const char *item_name = item->get_name();
220 if (item_name ==
nullptr) {
227 if (item_name == name_cstr) {
231 return strcmp(name_cstr, item_name) == 0;
235 void execute_item_(SchedulerItem *item, uint32_t now);
238 bool should_skip_item_(
const SchedulerItem *item)
const {
239 return item->remove || (item->component !=
nullptr && item->component->is_failed());
246 bool is_item_removed_(SchedulerItem *item)
const {
247#ifdef ESPHOME_THREAD_MULTI_ATOMICS
249 return item->remove.load(std::memory_order_acquire);
261 void mark_item_removed_(SchedulerItem *item) {
262#ifdef ESPHOME_THREAD_MULTI_ATOMICS
264 item->remove.store(
true, std::memory_order_release);
274 template<
typename Container>
275 bool has_cancelled_timeout_in_container_(
const Container &container, Component *component,
const char *name_cstr,
276 bool match_retry)
const {
277 for (
const auto &item : container) {
278 if (item->remove && this->matches_item_(item, component, name_cstr, SchedulerItem::TIMEOUT, match_retry,
287 std::vector<std::unique_ptr<SchedulerItem>> items_;
288 std::vector<std::unique_ptr<SchedulerItem>> to_add_;
289#ifndef ESPHOME_THREAD_SINGLE
291 std::deque<std::unique_ptr<SchedulerItem>> defer_queue_;
295#ifdef ESPHOME_THREAD_MULTI_ATOMICS
306 std::atomic<uint32_t> last_millis_{0};
318#ifdef ESPHOME_THREAD_MULTI_ATOMICS
319 std::atomic<uint16_t> millis_major_{0};
321 uint16_t millis_major_{0};
Providing packet encoding functions for exchanging data with a remote host.
void retry_handler(const std::shared_ptr< RetryArgs > &args)