mrs_lib
Various reusable classes, functions and utilities for use in MRS projects
Loading...
Searching...
No Matches
event.hpp
1#ifndef MRS_LIB_CORO_EVENT_HPP_
2#define MRS_LIB_CORO_EVENT_HPP_
3
4
5#include <memory>
6#include <coroutine>
7#include <mutex>
8#include <cassert>
9#include <optional>
10#include <utility>
11
12#include "mrs_lib/coro/internal/continuation.hpp"
13#include "mrs_lib/coro/internal/immediate_awaitable.hpp"
14
15
16namespace mrs_lib::coro
17{
18
19 class Event;
20 class EventAwaitable;
21
31 std::pair<Event, EventAwaitable> make_event();
32
36 class EventError : std::logic_error
37 {
38 public:
39 enum class Type
40 {
41 empty_awaitable_state,
42 };
43
44 EventError(Type type);
45
46 private:
47 static const char* get_msg(Type type);
48
49 Type type_;
50 };
51
52 namespace internal
53 {
54
59 {
60 private:
61 enum class Status
62 {
63 unset,
64 set,
65 cancelled,
66 };
67
71 struct StopCallbackCallable
72 {
73 EventState* event_state;
74
75 void operator()();
76 };
77
78 public:
85 bool try_trigger();
86
93 bool try_cancel();
94
111 bool add_continuation(CancellableContinuation continuation, bool token_cancelable, std::function<void()> callback);
112
120 bool is_ready();
121
122 private:
123 std::mutex mutex_{};
124 Status status_ = Status::unset;
125 internal::CancellableContinuation continuation_{};
126
127 std::optional<std::stop_callback<StopCallbackCallable>> stop_callback_{};
128 };
129
136 {
137 public:
138 class [[nodiscard]] Awaiter
139 {
140 public:
141 explicit Awaiter(std::shared_ptr<internal::EventState> state, bool token_cancellable, std::function<void()> callback);
142
143 bool await_ready();
144 template <typename T>
145 bool await_suspend(std::coroutine_handle<T> handle)
146 {
147 return await_suspend(CancellableContinuation(handle));
148 }
149 bool await_suspend(CancellableContinuation continuation);
150 void await_resume();
151
152 private:
153 std::shared_ptr<internal::EventState> state_;
154 bool is_token_cancellable_ = true;
155 std::function<void()> callback_;
156 };
157
158 enum class StopTokenBehavior
159 {
160 respect,
161 ignore,
162 };
163
164
165 ~LowLevelEventAwaitable() = default;
166
168 LowLevelEventAwaitable& operator=(const LowLevelEventAwaitable&) = delete;
170 LowLevelEventAwaitable& operator=(LowLevelEventAwaitable&& other) noexcept;
171
176
190 ImmediateAwaitable<Awaiter> get_awaitable(StopTokenBehavior stop_token_behavior, std::function<void()> callback) &&;
191
192 private:
193 explicit LowLevelEventAwaitable(std::shared_ptr<internal::EventState> state);
194
195 std::shared_ptr<internal::EventState> state_;
196
197 friend std::pair<Event, EventAwaitable> mrs_lib::coro::make_event();
198 };
199
203 LowLevelEventAwaitable get_low_level_event_awaitable(EventAwaitable event_awaitable);
204
205 } // namespace internal
206
216 class Event
217 {
218 public:
219 ~Event();
220
221 Event(const Event&) = delete;
222 Event& operator=(const Event&) = delete;
223
224 Event(Event&& other) noexcept;
225 Event& operator=(Event&& other) noexcept;
226
233 bool try_trigger();
234
241 bool try_cancel();
242
243 private:
244 explicit Event(std::shared_ptr<internal::EventState> state);
245
246 std::shared_ptr<internal::EventState> state_;
247
248 friend std::pair<Event, EventAwaitable> make_event();
249 };
250
261 {
262 public:
269 explicit EventAwaitable(internal::LowLevelEventAwaitable internal_awaitable);
270
281
282 private:
283 internal::LowLevelEventAwaitable internal_awaitable_;
284
285 friend internal::LowLevelEventAwaitable internal::get_low_level_event_awaitable(EventAwaitable event_awaitable);
286 };
287
288} // namespace mrs_lib::coro
289
290#endif // MRS_LIB_CORO_EVENT_HPP_
Event awaitable that can be awaited by coroutines, resuming them once triggered.
Definition event.hpp:261
auto wait() &&-> internal::ImmediateAwaitable< internal::LowLevelEventAwaitable::Awaiter >
Wait for the event to trigger / cancel.
Definition event.cpp:241
Exception thrown on incorrect use of Event/EventAwaitable.
Definition event.hpp:37
Event that can be used to trigger coroutines.
Definition event.hpp:217
bool try_trigger()
Try triggering the event.
Definition event.cpp:211
friend std::pair< Event, EventAwaitable > make_event()
Create Event and its bound awaitable.
Definition event.cpp:17
bool try_cancel()
Try cancelling the event.
Definition event.cpp:221
Owning coroutine handle supporting cancellation.
Definition continuation.hpp:54
Internal class for handling events.
Definition event.hpp:59
bool try_cancel()
Try cancelling the event state.
Definition event.cpp:73
bool try_trigger()
Try triggering the event state.
Definition event.cpp:50
bool is_ready()
Check if the event was already triggered.
Definition event.cpp:128
bool add_continuation(CancellableContinuation continuation, bool token_cancelable, std::function< void()> callback)
Store or resume the continuation as target for this event.
Definition event.cpp:93
Helper class to force awaiting a result in the current expression.
Definition immediate_awaitable.hpp:16
Internal awaitable used to wait for events.
Definition event.hpp:136
ImmediateAwaitable< Awaiter > get_awaitable() &&
Create awaitable for this event with default configuration.
Definition event.cpp:167