4#include <condition_variable>
21 std::atomic<bool> alive{
true};
22 std::atomic<bool> retired{
false};
24 std::condition_variable quiesced;
25 std::size_t active_leases = 0;
31 bool load(std::memory_order order = std::memory_order_seq_cst)
const noexcept {
32 return alive.load(order);
35 void store(
bool value, std::memory_order order = std::memory_order_seq_cst)
noexcept {
37 std::lock_guard lock(mutex);
38 retired.store(
true, std::memory_order_release);
39 alive.store(
false, order);
45 std::lock_guard lock(mutex);
46 if (retired.load(std::memory_order_acquire))
48 alive.store(
true, order);
53 using Handle = std::shared_ptr<State>;
70 state_ = std::move(
other.state_);
79 explicit operator bool() const noexcept {
80 return static_cast<bool>(state_);
93 void release() noexcept {
96 auto state = std::move(state_);
98 std::lock_guard lock(
state->mutex);
101 --
state->active_leases;
103 state->quiesced.notify_all();
128 const auto state = state_;
132 std::unique_lock lock(
state->mutex);
133 state->retired.store(
true, std::memory_order_release);
134 state->alive.store(
false, std::memory_order_release);
135 state->quiesced.wait(lock, [&
state] {
return state->active_leases == 0; });
140 state_ = std::make_shared<State>();
144 return handle && handle->alive.load(std::memory_order_acquire);
151 static bool is_alive(
const std::shared_ptr<std::atomic<bool>>& handle)
noexcept {
152 return handle && handle->load(std::memory_order_acquire);
168 std::lock_guard lock(handle->mutex);
169 if (handle->retired.load(std::memory_order_acquire) ||
170 !handle->alive.load(std::memory_order_acquire))
172 ++handle->active_leases;
173 return Lease(handle);
A temporary lease proving that an owner-backed callback may safely use its referenced state.
Definition alive_token.hpp:59
Lease & operator=(Lease &&other) noexcept
Definition alive_token.hpp:67
friend class AliveToken
Definition alive_token.hpp:89
~Lease()
Definition alive_token.hpp:75
void reset() noexcept
Release this callback's quiescence lease early.
Definition alive_token.hpp:84
std::shared_ptr< State > Handle
Definition alive_token.hpp:53
AliveToken(const AliveToken &)=delete
static bool is_alive(const Handle &handle) noexcept
Definition alive_token.hpp:143
void reset()
Definition alive_token.hpp:138
void retire() noexcept
Retire from the owner teardown context, outside any callback that holds a Lease.
Definition alive_token.hpp:127
AliveToken & operator=(AliveToken &&)=delete
static Lease try_acquire(const Handle &handle) noexcept
Atomically admit one callback before teardown can retire the owner.
Definition alive_token.hpp:165
AliveToken & operator=(const AliveToken &)=delete
~AliveToken()
Definition alive_token.hpp:110
AliveToken(AliveToken &&)=delete
static bool is_alive(const std::shared_ptr< std::atomic< bool > > &handle) noexcept
Definition alive_token.hpp:151
AliveToken()
Definition alive_token.hpp:109
Handle capture() const noexcept
Definition alive_token.hpp:119
Definition generated_event_source.hpp:33
@ other
Definition udev_monitor.hpp:26
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48