16#include "pw_assert/assert.h"
17#include "pw_async2/internal/config.h"
18#include "pw_async2/lock.h"
19#include "pw_containers/intrusive_forward_list.h"
20#include "pw_log/tokenized_args.h"
21#include "pw_sync/lock_annotations.h"
32template <
typename Callable>
33[[nodiscard]]
constexpr auto InvokeWithNodiscard(Callable&& callable) {
37[[nodiscard]]
bool CloneWaker(Waker& waker_in,
39 log::Token wait_reason = log::kDefaultToken)
40 PW_LOCKS_EXCLUDED(impl::dispatcher_lock());
58#define PW_ASYNC_STORE_WAKER(context, waker_or_queue_out, wait_reason_string) \
60 bool waker_or_queue_had_space = PW_ASYNC_TRY_STORE_WAKER( \
61 context, waker_or_queue_out, wait_reason_string); \
62 PW_ASSERT(waker_or_queue_had_space); \
79#define PW_ASYNC_TRY_STORE_WAKER( \
80 context, waker_or_queue_out, wait_reason_string) \
81 _PW_ASYNC_TRY_GET_WAKER(::pw::async2::internal::StoreWaker, \
100#define PW_ASYNC_CLONE_WAKER(waker_in, waker_or_queue_out, wait_reason_string) \
102 bool waker_or_queue_had_space = PW_ASYNC_TRY_CLONE_WAKER( \
103 waker_in, waker_or_queue_out, wait_reason_string); \
104 PW_ASSERT(waker_or_queue_had_space); \
121#define PW_ASYNC_TRY_CLONE_WAKER( \
122 waker_in, waker_or_queue_out, wait_reason_string) \
123 _PW_ASYNC_TRY_GET_WAKER(::pw::async2::internal::CloneWaker, \
125 waker_or_queue_out, \
129#define _PW_ASYNC_TRY_GET_WAKER( \
130 func, source, waker_or_queue_out, wait_reason_string) \
131 ::pw::async2::internal::InvokeWithNodiscard( \
132 [&]() PW_NO_LOCK_SAFETY_ANALYSIS { \
133 [[maybe_unused]] constexpr const char* \
134 pw_async2_wait_reason_must_be_string = wait_reason_string; \
135 constexpr ::pw::log::Token pw_async2_wait_reason = \
136 PW_LOG_TOKEN("pw_async2", wait_reason_string); \
137 return func(source, waker_or_queue_out, pw_async2_wait_reason); \
160 constexpr Waker() =
default;
161 Waker(
Waker&& other)
noexcept PW_LOCKS_EXCLUDED(impl::dispatcher_lock());
167 PW_LOCKS_EXCLUDED(impl::dispatcher_lock());
169 ~Waker() noexcept { RemoveFromTaskWakerList(); }
180 void Wake() && PW_LOCKS_EXCLUDED(impl::dispatcher_lock());
190 [[nodiscard]]
bool IsEmpty() const PW_LOCKS_EXCLUDED(impl::dispatcher_lock());
198 void Clear() PW_LOCKS_EXCLUDED(impl::dispatcher_lock()) {
199 RemoveFromTaskWakerList();
203 friend bool internal::CloneWaker(
Waker& waker_in,
205 log::Token wait_reason);
207 Waker(
Task& task) PW_LOCKS_EXCLUDED(impl::dispatcher_lock()) : task_(&task) {
208 InsertIntoTaskWakerList();
219 void InternalCloneIntoLocked(Waker& waker_out, log::Token wait_reason) &
220 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
222 void InsertIntoTaskWakerList();
223 void InsertIntoTaskWakerListLocked()
224 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
225 void RemoveFromTaskWakerList();
226 void RemoveFromTaskWakerListLocked()
227 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
230 Task* task_ PW_GUARDED_BY(impl::dispatcher_lock()) =
nullptr;
232#if PW_ASYNC2_DEBUG_WAIT_REASON
233 log::Token wait_reason_ = log::kDefaultToken;
Definition: intrusive_forward_list.h:86
Definition: dispatcher_base.h:47
Waker & operator=(Waker &&other) noexcept
void Clear()
Definition: waker.h:198
Definition: waker_queue.h:23