8#ifdef ESPHOME_THREAD_MULTI_ATOMICS
25 friend void ::esphome::retry_handler(
const std::shared_ptr<RetryArgs> &args);
30 template<
typename... Ts>
friend class DelayAction;
34 void set_timeout(Component *component,
const std::string &name, uint32_t timeout, std::function<
void()> func);
46 void set_timeout(Component *component,
const char *name, uint32_t timeout, std::function<
void()> func);
48 bool cancel_timeout(Component *component,
const std::string &name);
49 bool cancel_timeout(Component *component,
const char *name);
51 void set_interval(Component *component,
const std::string &name, uint32_t interval, std::function<
void()> func);
63 void set_interval(Component *component,
const char *name, uint32_t interval, std::function<
void()> func);
65 bool cancel_interval(Component *component,
const std::string &name);
66 bool cancel_interval(Component *component,
const char *name);
67 void set_retry(Component *component,
const std::string &name, uint32_t initial_wait_time, uint8_t max_attempts,
68 std::function<
RetryResult(uint8_t)> func,
float backoff_increase_factor = 1.0f);
69 void set_retry(Component *component,
const char *name, uint32_t initial_wait_time, uint8_t max_attempts,
70 std::function<
RetryResult(uint8_t)> func,
float backoff_increase_factor = 1.0f);
71 bool cancel_retry(Component *component,
const std::string &name);
72 bool cancel_retry(Component *component,
const char *name);
79 optional<uint32_t> next_schedule_in(uint32_t now);
83 void call(uint32_t now);
85 void process_to_add();
88 struct SchedulerItem {
93 const char *static_name;
105 std::function<void()> callback;
106 uint16_t next_execution_high_;
108#ifdef ESPHOME_THREAD_MULTI_ATOMICS
111 std::atomic<bool> remove{
false};
114 enum Type : uint8_t {
TIMEOUT, INTERVAL }
type : 1;
115 bool name_is_dynamic : 1;
121 enum Type : uint8_t {
TIMEOUT, INTERVAL }
type : 1;
123 bool name_is_dynamic : 1;
130 : component(nullptr),
132 next_execution_low_(0),
133 next_execution_high_(0),
134#ifdef ESPHOME_THREAD_MULTI_ATOMICS
137 name_is_dynamic(false),
142 name_is_dynamic(
false),
145 name_.static_name =
nullptr;
149 ~SchedulerItem() { clear_dynamic_name(); }
152 SchedulerItem(
const SchedulerItem &) =
delete;
153 SchedulerItem &operator=(
const SchedulerItem &) =
delete;
156 SchedulerItem(SchedulerItem &&) =
delete;
157 SchedulerItem &operator=(SchedulerItem &&) =
delete;
160 const char *get_name()
const {
return name_is_dynamic ? name_.dynamic_name : name_.static_name; }
163 void clear_dynamic_name() {
164 if (name_is_dynamic && name_.dynamic_name) {
165 delete[] name_.dynamic_name;
166 name_.dynamic_name =
nullptr;
167 name_is_dynamic =
false;
172 void set_name(
const char *name,
bool make_copy =
false) {
174 clear_dynamic_name();
178 name_.static_name =
nullptr;
179 }
else if (make_copy) {
181 size_t len = strlen(name);
182 name_.dynamic_name =
new char[
len + 1];
183 memcpy(name_.dynamic_name, name,
len + 1);
184 name_is_dynamic =
true;
187 name_.static_name = name;
191 static bool cmp(
const std::unique_ptr<SchedulerItem> &a,
const std::unique_ptr<SchedulerItem> &b);
196 constexpr uint64_t get_next_execution()
const {
197 return (
static_cast<uint64_t
>(next_execution_high_) << 32) | next_execution_low_;
200 constexpr void set_next_execution(uint64_t value) {
201 next_execution_low_ =
static_cast<uint32_t>(value);
204 next_execution_high_ =
static_cast<uint16_t
>(value >> 32);
206 constexpr const char *get_type_str()
const {
return (
type == TIMEOUT) ?
"timeout" :
"interval"; }
207 const LogString *get_source()
const {
return component ? component->get_component_log_str() : LOG_STR(
"unknown"); }
211 void set_timer_common_(Component *component, SchedulerItem::Type
type,
bool is_static_string,
const void *name_ptr,
212 uint32_t delay, std::function<
void()> func,
bool is_retry =
false,
bool skip_cancel =
false);
215 void set_retry_common_(Component *component,
bool is_static_string,
const void *name_ptr, uint32_t initial_wait_time,
216 uint8_t max_attempts, std::function<
RetryResult(uint8_t)> func,
float backoff_increase_factor);
218 uint64_t millis_64_(uint32_t now);
227 bool cancel_item_locked_(Component *component,
const char *name, SchedulerItem::Type
type,
bool match_retry =
false);
230 inline const char *get_name_cstr_(
bool is_static_string,
const void *name_ptr) {
231 return is_static_string ?
static_cast<const char *
>(name_ptr) : static_cast<const std::string *>(name_ptr)->c_str();
235 bool cancel_item_(Component *component,
bool is_static_string,
const void *name_ptr, SchedulerItem::Type
type);
238 inline bool HOT names_match_(
const char *name1,
const char *name2)
const {
243 return (name1 !=
nullptr && name2 !=
nullptr) && ((name1 == name2) || (strcmp(name1, name2) == 0));
247 inline bool HOT matches_item_(
const std::unique_ptr<SchedulerItem> &item, Component *component,
const char *name_cstr,
248 SchedulerItem::Type
type,
bool match_retry,
bool skip_removed =
true)
const {
249 if (item->component != component || item->type !=
type || (skip_removed && item->remove) ||
250 (match_retry && !item->is_retry)) {
253 return this->names_match_(item->get_name(), name_cstr);
257 uint32_t execute_item_(SchedulerItem *item, uint32_t now);
260 bool should_skip_item_(SchedulerItem *item)
const {
261 return is_item_removed_(item) || (item->component !=
nullptr && item->component->is_failed());
265 void recycle_item_(std::unique_ptr<SchedulerItem> item);
271 bool is_item_removed_(SchedulerItem *item)
const {
272#ifdef ESPHOME_THREAD_MULTI_ATOMICS
274 return item->remove.load(std::memory_order_acquire);
286 void mark_item_removed_(SchedulerItem *item) {
287#ifdef ESPHOME_THREAD_MULTI_ATOMICS
289 item->remove.store(
true, std::memory_order_release);
299 template<
typename Container>
300 bool has_cancelled_timeout_in_container_(
const Container &container, Component *component,
const char *name_cstr,
301 bool match_retry)
const {
302 for (
const auto &item : container) {
303 if (is_item_removed_(item.get()) &&
304 this->matches_item_(item, component, name_cstr, SchedulerItem::TIMEOUT, match_retry,
313 std::vector<std::unique_ptr<SchedulerItem>> items_;
314 std::vector<std::unique_ptr<SchedulerItem>> to_add_;
315#ifndef ESPHOME_THREAD_SINGLE
317 std::deque<std::unique_ptr<SchedulerItem>> defer_queue_;
329 std::vector<std::unique_ptr<SchedulerItem>> scheduler_item_pool_;
331#ifdef ESPHOME_THREAD_MULTI_ATOMICS
342 std::atomic<uint32_t> last_millis_{0};
354#ifdef ESPHOME_THREAD_MULTI_ATOMICS
355 std::atomic<uint16_t> millis_major_{0};
357 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)