16#include "pw_async2/dispatcher.h"
17#include "pw_async2/dispatcher_base.h"
18#include "pw_function/function.h"
19#include "pw_sync/mutex.h"
30 static NoDestructor<pw::sync::InterruptSpinLock> lock;
49 template <
typename... Args>
51 : value_(std::forward<Args>(value_args)...) {}
54 std::lock_guard lock(sender_receiver_lock());
55 sender_ = other.sender_;
56 other.sender_ =
nullptr;
58 sender_->receiver_ =
this;
60 if (other.value_.has_value()) {
61 value_.emplace(std::move(other.value_.value()));
64 waker_ = std::move(other.waker_);
67 OnceReceiver(
const OnceReceiver&) =
delete;
68 OnceReceiver& operator=(
const OnceReceiver&) =
delete;
69 OnceReceiver& operator=(OnceReceiver&& other) =
delete;
77 std::lock_guard lock(sender_receiver_lock());
78 if (value_.has_value()) {
79 return Ready(std::move(*value_));
80 }
else if (!sender_) {
86 "OnceReceiver is waiting for a value to be sent into the "
87 "corresponding OnceSender");
95 friend void InitializeOnceSenderAndReceiver(
OnceSender<U>& sender,
100 std::optional<T> value_
PW_GUARDED_BY(sender_receiver_lock()) = std::nullopt;
114 std::lock_guard lock(sender_receiver_lock());
116 std::move(receiver_->waker_).Wake();
117 receiver_->sender_ =
nullptr;
122 std::lock_guard lock(sender_receiver_lock());
123 receiver_ = other.receiver_;
124 other.receiver_ =
nullptr;
126 receiver_->sender_ =
this;
135 template <
typename... Args>
137 std::lock_guard lock(sender_receiver_lock());
139 receiver_->value_.emplace(std::forward<Args>(args)...);
140 std::move(receiver_->waker_).Wake();
141 receiver_->sender_ =
nullptr;
150 OnceSender& operator=(T&& value) {
156 template <
typename U>
158 template <
typename U>
159 friend void InitializeOnceSenderAndReceiver(OnceSender<U>& sender,
160 OnceReceiver<U>& receiver);
161 friend class OnceReceiver<T>;
163 OnceSender(OnceReceiver<T>* receiver) : receiver_(receiver) {}
165 OnceReceiver<T>* receiver_
PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
169OnceReceiver<T>::~OnceReceiver() {
170 std::lock_guard lock(sender_receiver_lock());
172 sender_->receiver_ =
nullptr;
191 receiver.sender_ = &sender;
192 sender.receiver_ = &receiver;
211 std::lock_guard lock(sender_receiver_lock());
212 sender_ = other.sender_;
213 other.sender_ =
nullptr;
215 sender_->receiver_ =
this;
217 value_ = other.value_;
218 waker_ = std::move(other.waker_);
231 std::lock_guard lock(sender_receiver_lock());
232 if (value_ ==
nullptr) {
235 if (sender_ ==
nullptr) {
241 "OnceRefReceiver is waiting for OnceRefSender to write a value");
246 template <
typename U>
248 MakeOnceRefSenderAndReceiver(U&);
249 template <
typename U>
261 OnceRefSender<T>* sender_
PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
275 std::lock_guard lock(sender_receiver_lock());
277 receiver_->sender_ =
nullptr;
278 std::move(receiver_->waker_).Wake();
283 std::lock_guard lock(sender_receiver_lock());
284 receiver_ = other.receiver_;
285 other.receiver_ =
nullptr;
287 receiver_->sender_ =
this;
296 void Set(
const T& value) {
297 std::lock_guard lock(sender_receiver_lock());
299 *(receiver_->value_) = value;
300 std::move(receiver_->waker_).Wake();
301 receiver_->sender_ =
nullptr;
302 receiver_->value_ =
nullptr;
309 std::lock_guard lock(sender_receiver_lock());
311 *(receiver_->value_) = std::move(value);
312 std::move(receiver_->waker_).Wake();
313 receiver_->sender_ =
nullptr;
314 receiver_->value_ =
nullptr;
324 std::lock_guard lock(sender_receiver_lock());
327 func(*(receiver_->value_));
334 std::lock_guard lock(sender_receiver_lock());
336 std::move(receiver_->waker_).Wake();
337 receiver_->sender_ =
nullptr;
338 receiver_->value_ =
nullptr;
344 template <
typename U>
346 MakeOnceRefSenderAndReceiver(U&);
347 template <
typename U>
355 OnceRefReceiver<T>* receiver_
PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
359OnceRefReceiver<T>::~OnceRefReceiver() {
360 std::lock_guard lock(sender_receiver_lock());
362 sender_->receiver_ =
nullptr;
388 receiver.sender_ = &sender;
389 receiver.value_ = &value;
390 sender.receiver_ = &receiver;
static constexpr Status Cancelled()
Operation was cancelled, typically by the caller.
Definition: status.h:121
Definition: once_sender.h:43
friend std::pair< OnceSender< U >, OnceReceiver< U > > MakeOnceSenderAndReceiver()
Construct a pair of OnceSender and OnceReceiver.
Definition: once_sender.h:178
OnceReceiver(Args &&... value_args)
Definition: once_sender.h:50
PollResult< T > Pend(Context &cx)
Definition: once_sender.h:76
Definition: once_sender.h:206
Poll< Status > Pend(Context &cx)
Definition: once_sender.h:230
Definition: once_sender.h:270
void Set(const T &value)
Copy assigns the reference and awakens the receiver.
Definition: once_sender.h:296
void Set(T &&value)
Move assigns the reference and awakens the receiver.
Definition: once_sender.h:308
void Commit()
Definition: once_sender.h:333
void ModifyUnsafe(pw::Function< void(T &)> func)
Definition: once_sender.h:323
Definition: once_sender.h:109
friend std::pair< OnceSender< U >, OnceReceiver< U > > MakeOnceSenderAndReceiver()
Construct a pair of OnceSender and OnceReceiver.
Definition: once_sender.h:178
void emplace(Args &&... args)
Construct the sent value in place and wake the OnceReceiver.
Definition: once_sender.h:136
Definition: interrupt_spin_lock.h:50
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:271
#define PW_ASYNC_STORE_WAKER(context, waker_or_queue_out, wait_reason_string)
Definition: waker.h:60
constexpr Poll Ready()
Returns a value indicating completion.
Definition: poll.h:255
void InitializeOnceSenderAndReceiver(OnceSender< T > &sender, OnceReceiver< T > &receiver)
Initialize a pair of OnceSender and OnceReceiver.
Definition: once_sender.h:186
std::pair< OnceSender< T >, OnceReceiver< T > > MakeOnceSenderAndReceiver()
Construct a pair of OnceSender and OnceReceiver.
Definition: once_sender.h:178
std::pair< OnceRefSender< T >, OnceRefReceiver< T > > MakeOnceRefSenderAndReceiver(T &value)
Definition: once_sender.h:371
void InitializeOnceRefSenderAndReceiver(OnceRefSender< T > &sender, OnceRefReceiver< T > &receiver, T &value)
Definition: once_sender.h:383
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:73
constexpr Status OkStatus()
Definition: status.h:297
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
#define PW_NO_LOCK_SAFETY_ANALYSIS
Definition: lock_annotations.h:292