sdbus-c++
2.3.1
High-level C++ D-Bus library based on systemd D-Bus implementation
Toggle main menu visibility
Loading...
Searching...
No Matches
Awaitable.h
Go to the documentation of this file.
1
27
28
#ifndef SDBUS_CXX_AWAITABLE_H_
29
#define SDBUS_CXX_AWAITABLE_H_
30
31
#include <atomic>
32
#include <cassert>
33
#if __has_include(<coroutine>)
34
#include <coroutine>
35
#endif
36
#include <cstdint>
37
#include <exception>
38
#include <memory>
39
#include <type_traits>
40
#include <variant>
41
42
namespace
sdbus {
43
44
// Forward declarations
45
class
AsyncMethodInvoker
;
46
namespace
internal {
47
class
Proxy;
48
}
// namespace internal
49
50
/********************************************/
59
enum class
AwaitableState
: uint8_t
60
{
61
NotReady,
// Initial state: callback hasn't fired yet
62
Waiting,
// Coroutine is suspended and waiting for callback
63
Completed
// Callback completed, result is ready
64
};
65
66
// Shared data
67
template
<
typename
T>
68
struct
AwaitableData
69
{
70
using
result_type = std::conditional_t<std::is_void_v<T>, std::monostate, T>;
71
std::variant<result_type, std::exception_ptr> result;
72
std::atomic<AwaitableState> status{AwaitableState::NotReady};
73
#ifdef __cpp_lib_coroutine
74
// Keep the handle as the last member to mainting ABI compatibility
75
// with clients without coroutine support.
76
std::coroutine_handle<> handle;
77
#endif
// __cpp_lib_coroutine
78
79
void
resumeCoroutine()
80
{
81
#ifdef __cpp_lib_coroutine
82
handle.resume();
83
#endif
// __cpp_lib_coroutine
84
}
85
};
86
87
/********************************************/
108
template
<
typename
T>
109
class
Awaitable
110
{
111
#ifdef __cpp_lib_coroutine
112
public
:
113
// Called when the coroutine is co_await'ed. Returns true if the coroutine should be suspended.
114
[[nodiscard]]
bool
await_ready()
const
noexcept
115
{
116
return
data_->status.load(std::memory_order_acquire) == AwaitableState::Completed;
117
}
118
119
// Called when the coroutine is suspended, returning false here will immediately
120
// resume the coroutine.
121
bool
await_suspend(std::coroutine_handle<> handle)
noexcept
122
{
123
data_->handle = handle;
124
125
// Attempt transition from NotReady to Waiting.
126
AwaitableState
expected = AwaitableState::NotReady;
127
return
data_->status.compare_exchange_strong(expected, AwaitableState::Waiting, std::memory_order_acq_rel);
128
}
129
130
// Called when the coroutine is resumed. Returns the result or throws the exception.
131
[[nodiscard]] T await_resume()
const
132
{
133
if
(
auto
* exception = std::get_if<std::exception_ptr>(&data_->result); exception !=
nullptr
)
134
std::rethrow_exception(*exception);
135
136
if
constexpr
(std::is_void_v<T>)
137
return
;
138
else
139
return
std::get<T>(std::move(data_->result));
140
}
141
#endif
// __cpp_lib_coroutine
142
143
private
:
144
friend
internal::Proxy;
145
friend
AsyncMethodInvoker;
146
147
explicit
Awaitable(std::shared_ptr<
AwaitableData<T>
> data)
148
: data_(std::move(data))
149
{
150
assert(data_ !=
nullptr
);
151
}
152
153
std::shared_ptr<AwaitableData<T>> data_;
154
};
155
156
}
// namespace sdbus
157
158
#endif
// SDBUS_CXX_AWAITABLE_H_
sdbus::AwaitableState
AwaitableState
Definition
Awaitable.h:60
sdbus::AsyncMethodInvoker
Definition
ConvenienceApiClasses.h:128
sdbus::AwaitableData
Definition
Awaitable.h:69
include
sdbus-c++
Awaitable.h
Generated by
1.17.0