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"
28 static NoDestructor<pw::sync::InterruptSpinLock> lock;
47 template <
typename... Args>
49 : value_(std::forward<Args>(value_args)...) {}
52 std::lock_guard lock(sender_receiver_lock());
53 sender_ = other.sender_;
54 other.sender_ =
nullptr;
56 sender_->receiver_ =
this;
58 if (other.value_.has_value()) {
59 value_.emplace(std::move(other.value_.value()));
62 waker_ = std::move(other.waker_);
65 OnceReceiver(
const OnceReceiver&) =
delete;
66 OnceReceiver& operator=(
const OnceReceiver&) =
delete;
67 OnceReceiver& operator=(OnceReceiver&& other) =
delete;
75 std::lock_guard lock(sender_receiver_lock());
76 if (value_.has_value()) {
77 return Ready(std::move(*value_));
78 }
else if (!sender_) {
79 return Ready(Status::Cancelled());
84 "OnceReceiver is waiting for a value to be sent into the "
85 "corresponding OnceSender");
93 friend void InitializeOnceSenderAndReceiver(
OnceSender<U>& sender,
97 OnceSender<T>* sender_ PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
98 std::optional<T> value_ PW_GUARDED_BY(sender_receiver_lock()) = std::nullopt;
112 std::lock_guard lock(sender_receiver_lock());
114 std::move(receiver_->waker_).Wake();
115 receiver_->sender_ =
nullptr;
120 std::lock_guard lock(sender_receiver_lock());
121 receiver_ = other.receiver_;
122 other.receiver_ =
nullptr;
124 receiver_->sender_ =
this;
133 template <
typename... Args>
135 std::lock_guard lock(sender_receiver_lock());
137 receiver_->value_.emplace(std::forward<Args>(args)...);
138 std::move(receiver_->waker_).Wake();
139 receiver_->sender_ =
nullptr;
148 OnceSender& operator=(T&& value) {
154 template <
typename U>
156 template <
typename U>
157 friend void InitializeOnceSenderAndReceiver(OnceSender<U>& sender,
158 OnceReceiver<U>& receiver);
159 friend class OnceReceiver<T>;
161 OnceSender(OnceReceiver<T>* receiver) : receiver_(receiver) {}
163 OnceReceiver<T>* receiver_ PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
167OnceReceiver<T>::~OnceReceiver() {
168 std::lock_guard lock(sender_receiver_lock());
170 sender_->receiver_ =
nullptr;
178 InitializeOnceSenderAndReceiver(send_recv.first, send_recv.second);
186 PW_NO_LOCK_SAFETY_ANALYSIS {
189 receiver.sender_ = &sender;
190 sender.receiver_ = &receiver;
209 std::lock_guard lock(sender_receiver_lock());
210 sender_ = other.sender_;
211 other.sender_ =
nullptr;
213 sender_->receiver_ =
this;
215 value_ = other.value_;
216 waker_ = std::move(other.waker_);
229 std::lock_guard lock(sender_receiver_lock());
230 if (value_ ==
nullptr) {
233 if (sender_ ==
nullptr) {
234 return Ready(Status::Cancelled());
236 PW_ASYNC_STORE_WAKER(
239 "OnceRefReceiver is waiting for OnceRefSender to write a value");
244 template <
typename U>
246 MakeOnceRefSenderAndReceiver(U&);
247 template <
typename U>
257 T* value_ PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
259 OnceRefSender<T>* sender_ PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
273 std::lock_guard lock(sender_receiver_lock());
275 receiver_->sender_ =
nullptr;
276 std::move(receiver_->waker_).Wake();
281 std::lock_guard lock(sender_receiver_lock());
282 receiver_ = other.receiver_;
283 other.receiver_ =
nullptr;
285 receiver_->sender_ =
this;
294 void Set(
const T& value) {
295 std::lock_guard lock(sender_receiver_lock());
297 *(receiver_->value_) = value;
298 std::move(receiver_->waker_).Wake();
299 receiver_->sender_ =
nullptr;
300 receiver_->value_ =
nullptr;
307 std::lock_guard lock(sender_receiver_lock());
309 *(receiver_->value_) = std::move(value);
310 std::move(receiver_->waker_).Wake();
311 receiver_->sender_ =
nullptr;
312 receiver_->value_ =
nullptr;
322 std::lock_guard lock(sender_receiver_lock());
325 func(*(receiver_->value_));
332 std::lock_guard lock(sender_receiver_lock());
334 std::move(receiver_->waker_).Wake();
335 receiver_->sender_ =
nullptr;
336 receiver_->value_ =
nullptr;
342 template <
typename U>
344 MakeOnceRefSenderAndReceiver(U&);
345 template <
typename U>
353 OnceRefReceiver<T>* receiver_ PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
357OnceRefReceiver<T>::~OnceRefReceiver() {
358 std::lock_guard lock(sender_receiver_lock());
360 sender_->receiver_ =
nullptr;
369std::pair<OnceRefSender<T>, OnceRefReceiver<T>> MakeOnceRefSenderAndReceiver(
371 std::pair<OnceRefSender<T>, OnceRefReceiver<T>> send_recv;
372 InitializeOnceRefSenderAndReceiver(send_recv.first, send_recv.second, value);
381void InitializeOnceRefSenderAndReceiver(OnceRefSender<T>& sender,
382 OnceRefReceiver<T>& receiver,
383 T& value) PW_NO_LOCK_SAFETY_ANALYSIS {
386 receiver.sender_ = &sender;
387 receiver.value_ = &value;
388 sender.receiver_ = &receiver;
Definition: dispatcher_base.h:52
Definition: once_sender.h:41
friend std::pair< OnceSender< U >, OnceReceiver< U > > MakeOnceSenderAndReceiver()
Construct a pair of OnceSender and OnceReceiver.
Definition: once_sender.h:176
Poll< Result< T > > Pend(Context &cx)
Definition: once_sender.h:74
OnceReceiver(Args &&... value_args)
Definition: once_sender.h:48
Definition: once_sender.h:204
Poll< Status > Pend(Context &cx)
Definition: once_sender.h:228
Definition: once_sender.h:268
void Set(const T &value)
Copy assigns the reference and awakens the receiver.
Definition: once_sender.h:294
void Set(T &&value)
Move assigns the reference and awakens the receiver.
Definition: once_sender.h:306
void Commit()
Definition: once_sender.h:331
void ModifyUnsafe(pw::Function< void(T &)> func)
Definition: once_sender.h:321
Definition: once_sender.h:107
friend std::pair< OnceSender< U >, OnceReceiver< U > > MakeOnceSenderAndReceiver()
Construct a pair of OnceSender and OnceReceiver.
Definition: once_sender.h:176
void emplace(Args &&... args)
Construct the sent value in place and wake the OnceReceiver.
Definition: once_sender.h:134
Definition: dispatcher_base.h:318
Definition: interrupt_spin_lock.h:48
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:74
constexpr Status OkStatus()
Definition: status.h:234