16#include "pw_async2/dispatcher.h"
17#include "pw_function/function.h"
18#include "pw_sync/mutex.h"
29 static NoDestructor<pw::sync::InterruptSpinLock> lock;
48 template <
typename... Args>
50 : value_(std::forward<Args>(value_args)...) {}
53 std::lock_guard lock(sender_receiver_lock());
54 sender_ = other.sender_;
55 other.sender_ =
nullptr;
57 sender_->receiver_ =
this;
59 if (other.value_.has_value()) {
60 value_.emplace(std::move(other.value_.value()));
63 waker_ = std::move(other.waker_);
66 OnceReceiver(
const OnceReceiver&) =
delete;
67 OnceReceiver& operator=(
const OnceReceiver&) =
delete;
68 OnceReceiver& operator=(OnceReceiver&& other) =
delete;
76 std::lock_guard lock(sender_receiver_lock());
77 if (value_.has_value()) {
78 return Ready(std::move(*value_));
79 }
else if (!sender_) {
85 "OnceReceiver is waiting for a value to be sent into the "
86 "corresponding OnceSender");
94 friend void InitializeOnceSenderAndReceiver(
OnceSender<U>& sender,
99 std::optional<T> value_
PW_GUARDED_BY(sender_receiver_lock()) = std::nullopt;
113 std::lock_guard lock(sender_receiver_lock());
115 std::move(receiver_->waker_).Wake();
116 receiver_->sender_ =
nullptr;
121 std::lock_guard lock(sender_receiver_lock());
122 receiver_ = other.receiver_;
123 other.receiver_ =
nullptr;
125 receiver_->sender_ =
this;
134 template <
typename... Args>
136 std::lock_guard lock(sender_receiver_lock());
138 receiver_->value_.emplace(std::forward<Args>(args)...);
139 std::move(receiver_->waker_).Wake();
140 receiver_->sender_ =
nullptr;
149 OnceSender& operator=(T&& value) {
155 template <
typename U>
157 template <
typename U>
158 friend void InitializeOnceSenderAndReceiver(OnceSender<U>& sender,
159 OnceReceiver<U>& receiver);
160 friend class OnceReceiver<T>;
162 OnceSender(OnceReceiver<T>* receiver) : receiver_(receiver) {}
164 OnceReceiver<T>* receiver_
PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
168OnceReceiver<T>::~OnceReceiver() {
169 std::lock_guard lock(sender_receiver_lock());
171 sender_->receiver_ =
nullptr;
190 receiver.sender_ = &sender;
191 sender.receiver_ = &receiver;
210 std::lock_guard lock(sender_receiver_lock());
211 sender_ = other.sender_;
212 other.sender_ =
nullptr;
214 sender_->receiver_ =
this;
216 value_ = other.value_;
217 waker_ = std::move(other.waker_);
230 std::lock_guard lock(sender_receiver_lock());
231 if (value_ ==
nullptr) {
234 if (sender_ ==
nullptr) {
240 "OnceRefReceiver is waiting for OnceRefSender to write a value");
245 template <
typename U>
247 MakeOnceRefSenderAndReceiver(U&);
248 template <
typename U>
260 OnceRefSender<T>* sender_
PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
274 std::lock_guard lock(sender_receiver_lock());
276 receiver_->sender_ =
nullptr;
277 std::move(receiver_->waker_).Wake();
282 std::lock_guard lock(sender_receiver_lock());
283 receiver_ = other.receiver_;
284 other.receiver_ =
nullptr;
286 receiver_->sender_ =
this;
295 void Set(
const T& value) {
296 std::lock_guard lock(sender_receiver_lock());
298 *(receiver_->value_) = value;
299 std::move(receiver_->waker_).Wake();
300 receiver_->sender_ =
nullptr;
301 receiver_->value_ =
nullptr;
308 std::lock_guard lock(sender_receiver_lock());
310 *(receiver_->value_) = std::move(value);
311 std::move(receiver_->waker_).Wake();
312 receiver_->sender_ =
nullptr;
313 receiver_->value_ =
nullptr;
323 std::lock_guard lock(sender_receiver_lock());
326 func(*(receiver_->value_));
333 std::lock_guard lock(sender_receiver_lock());
335 std::move(receiver_->waker_).Wake();
336 receiver_->sender_ =
nullptr;
337 receiver_->value_ =
nullptr;
343 template <
typename U>
345 MakeOnceRefSenderAndReceiver(U&);
346 template <
typename U>
354 OnceRefReceiver<T>* receiver_
PW_GUARDED_BY(sender_receiver_lock()) =
nullptr;
358OnceRefReceiver<T>::~OnceRefReceiver() {
359 std::lock_guard lock(sender_receiver_lock());
361 sender_->receiver_ =
nullptr;
387 receiver.sender_ = &sender;
388 receiver.value_ = &value;
389 sender.receiver_ = &receiver;
static constexpr Status Cancelled()
Definition: status.h:139
Definition: once_sender.h:42
friend std::pair< OnceSender< U >, OnceReceiver< U > > MakeOnceSenderAndReceiver()
Construct a pair of OnceSender and OnceReceiver.
Definition: once_sender.h:177
OnceReceiver(Args &&... value_args)
Definition: once_sender.h:49
PollResult< T > Pend(Context &cx)
Definition: once_sender.h:75
Definition: once_sender.h:205
Poll< Status > Pend(Context &cx)
Definition: once_sender.h:229
Definition: once_sender.h:269
void Set(const T &value)
Copy assigns the reference and awakens the receiver.
Definition: once_sender.h:295
void Set(T &&value)
Move assigns the reference and awakens the receiver.
Definition: once_sender.h:307
void Commit()
Definition: once_sender.h:332
void ModifyUnsafe(pw::Function< void(T &)> func)
Definition: once_sender.h:322
Definition: once_sender.h:108
friend std::pair< OnceSender< U >, OnceReceiver< U > > MakeOnceSenderAndReceiver()
Construct a pair of OnceSender and OnceReceiver.
Definition: once_sender.h:177
void emplace(Args &&... args)
Construct the sent value in place and wake the OnceReceiver.
Definition: once_sender.h:135
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:185
std::pair< OnceSender< T >, OnceReceiver< T > > MakeOnceSenderAndReceiver()
Construct a pair of OnceSender and OnceReceiver.
Definition: once_sender.h:177
std::pair< OnceRefSender< T >, OnceRefReceiver< T > > MakeOnceRefSenderAndReceiver(T &value)
Definition: once_sender.h:370
void InitializeOnceRefSenderAndReceiver(OnceRefSender< T > &sender, OnceRefReceiver< T > &receiver, T &value)
Definition: once_sender.h:382
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:450
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
#define PW_NO_LOCK_SAFETY_ANALYSIS
Definition: lock_annotations.h:292