28 std::optional<T> Slot_;
29 std::coroutine_handle<> Handle_;
30 bool Registered_ =
false;
32 explicit ReceiveAwaiter (
Channel& ch)
41 std::lock_guard guard { Ch_.Lock_ };
42 std::erase (Ch_.Awaiters_,
this);
46 bool await_ready ()
const noexcept
51 bool await_suspend (std::coroutine_handle<> handle)
53 std::lock_guard guard { Ch_.Lock_ };
54 if (!Ch_.Elems_.empty ())
56 Slot_ = std::move (Ch_.Elems_.front ());
57 Ch_.Elems_.pop_front ();
64 Ch_.Awaiters_.push_back (
this);
70 std::optional<T> await_resume ()
noexcept
72 return std::move (Slot_);
76 mutable std::mutex Lock_;
78 std::deque<ReceiveAwaiter*> Awaiters_;
80 std::function<void (std::coroutine_handle<>)> RunHandle_ { [] (std::coroutine_handle<> handle) { handle (); } };
94 : RunHandle_ { [context] (auto handle) { QMetaObject::invokeMethod (context, handle); } }
100 std::deque<ReceiveAwaiter*> awaiters;
103 std::lock_guard guard { Lock_ };
108 awaiters = std::exchange (Awaiters_, {});
109 for (
auto awaiter : awaiters)
110 awaiter->Registered_ =
false;
113 for (
auto awaiter : awaiters)
114 RunHandle_ (awaiter->Handle_);
117 template<
typename U = T>
120 ReceiveAwaiter *next =
nullptr;
122 std::lock_guard guard { Lock_ };
124 throw std::runtime_error {
"sending into a closed channel" };
126 if (!Awaiters_.empty ())
128 next = Awaiters_.front ();
129 Awaiters_.pop_front ();
130 next->Registered_ =
false;
133 Elems_.emplace_back (std::forward<U> (value));
138 next->Slot_.emplace (std::forward<U> (value));
139 RunHandle_ (next->Handle_);
145 std::lock_guard guard { Lock_ };
146 return Elems_.empty ();
151 return ReceiveAwaiter { *
this };
154 auto operator co_await ()