You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* @remark - This object's methods, other than constructors and operators, should not be called directly. It is designed to be used with coroutine keywords such as co_await.
42
115
* @remark - The coroutine may be resumed in another thread, do not rely on thread_local variables.
43
116
* @warning - This feature is EXPERIMENTAL. The API may change at any time and there may be bugs. Please report any to <a href="https://github.com/brainboxdotcc/DPP/issues">GitHub issues</a> or to the <a href="https://discord.gg/dpp">D++ Discord server</a>.
44
-
* @warning - Using co_await on this object more than once is undefined behavior.
45
117
* @tparam R The return type of the API call. Defaults to confirmation_callback_t
46
118
*/
47
119
template <typename R>
@@ -50,97 +122,35 @@ class async {
50
122
* @brief Ref-counted callback, contains the callback logic and manages the lifetime of the callback data over multiple threads.
51
123
*/
52
124
structshared_callback {
53
-
structempty_tag_t{};
54
-
55
-
/**
56
-
* @brief State of the async and its callback.
57
-
*/
58
-
structcallback_state {
59
-
enumstate_t {
60
-
waiting,
61
-
done,
62
-
dangling
63
-
};
64
-
65
-
/**
66
-
* @brief Mutex to ensure the API result isn't set at the same time the coroutine is awaited and its value is checked, or the async is destroyed
67
-
*/
68
-
std::mutex mutex{};
69
-
70
-
/**
71
-
* @brief Number of references to this callback state.
72
-
*/
73
-
int ref_count;
74
-
75
-
/**
76
-
* @brief State of the awaitable and the API callback
77
-
*/
78
-
state_t state = waiting;
79
-
80
-
/**
81
-
* @brief The stored result of the API call
82
-
*/
83
-
std::optional<R> result = std::nullopt;
84
-
85
-
/**
86
-
* @brief Handle to the coroutine co_await-ing on this API call
* @brief Function called by the async when it is destroyed when it was never co_awaited, signals to the callback to abort.
177
196
*/
178
-
voidset_dangling() {
197
+
voidset_dangling() noexcept{
179
198
if (!state) // moved-from object
180
199
return;
181
-
std::lock_guard lock{get_mutex()};
200
+
/*
201
+
If the state is sent but not awaited, set it to dangling, in a relaxed memory order (we don't care if the callback thread actually sees it).
202
+
"sent" is the only state we care about to set it to dangling, as if it's done it's not dangling, and if it's waiting... Something went seriously wrong and shouldn't be happening.
returntrue; // suspend the caller, the callback will resume it
342
+
return api_callback.state->state.compare_exchange_strong(sent, detail::async_state_t::waiting); // true (suspend) if `sent` was replaced with `waiting` -- false (resume) if the value was not `sent` (`done` is the only other option)
343
+
}
344
+
345
+
/**
346
+
* @brief Function called by the standard library when the async is resumed. Its return value is what the whole co_await expression evaluates to
347
+
*
348
+
* @remark Do not call this manually, use the co_await keyword instead.
349
+
* @return R& The result of the API call as an lvalue reference.
350
+
*/
351
+
R& await_resume() & noexcept {
352
+
return api_callback.get_result();
353
+
}
354
+
355
+
356
+
/**
357
+
* @brief Function called by the standard library when the async is resumed. Its return value is what the whole co_await expression evaluates to
358
+
*
359
+
* @remark Do not call this manually, use the co_await keyword instead.
360
+
* @return const R& The result of the API call as a const lvalue reference.
361
+
*/
362
+
const R& await_resume() const& noexcept {
363
+
return api_callback.get_result();
318
364
}
365
+
319
366
320
367
/**
321
368
* @brief Function called by the standard library when the async is resumed. Its return value is what the whole co_await expression evaluates to
322
369
*
323
370
* @remark Do not call this manually, use the co_await keyword instead.
324
-
* @return R The result of the API call.
371
+
* @return R&& The result of the API call as an rvalue reference.
325
372
*/
326
-
R await_resume() {
327
-
// no locking needed here as the callback has already executed
0 commit comments