Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
cancel.hpp
Go to the documentation of this file.
1#pragma once
2
3// Cooperative cancellation.
4//
5// CancelSource - move-only owner. Calls `cancel()`, and cancels on destruction.
6// CancelToken - copyable observer handed to the work being cancelled.
7// CancelRegistration - RAII handle for a callback registered on a token.
8//
9// A default-constructed CancelToken is never cancelled, so APIs can take a
10// `const CancelToken& = {}` parameter and treat "no token" as "cannot be
11// cancelled" without a null check.
12//
13// Threading: every member is safe to call from any thread. `is_cancelled()` is
14// a single acquire load of a lock-free atomic. It never locks and never
15// allocates, so it may be polled from the audio thread. Everything else
16// (`wait_for_cancellation`, `register_callback`, `cancel`) takes a mutex and
17// may allocate, and must stay off the audio thread.
18
19#include <atomic>
20#include <chrono>
21#include <cstdint>
22#include <functional>
23#include <memory>
24
25namespace pulp::runtime {
26
27class CancelToken;
28class CancelSource;
29
30namespace detail {
34 std::atomic<bool> cancelled{false};
35 virtual ~CancelStateBase() = default;
36};
37} // namespace detail
38
42using CancelCallback = std::function<void()>;
43
51 public:
52 CancelRegistration() noexcept = default;
54
56 CancelRegistration& operator=(const CancelRegistration&) = delete;
59
61 [[nodiscard]] explicit operator bool() const noexcept {
62 return id_ != 0;
63 }
64
66 void reset() noexcept;
67
68 private:
69 friend class CancelToken;
70 CancelRegistration(std::shared_ptr<detail::CancelStateBase> state, std::uint64_t id) noexcept
71 : state_(std::move(state)), id_(id) {}
72
73 std::shared_ptr<detail::CancelStateBase> state_;
74 std::uint64_t id_ = 0;
75};
76
78 public:
80 CancelToken() noexcept = default;
81
84 [[nodiscard]] bool is_cancelled() const noexcept {
85 return state_ && state_->cancelled.load(std::memory_order_acquire);
86 }
87
89 [[nodiscard]] bool can_be_cancelled() const noexcept {
90 return state_ != nullptr;
91 }
92
96 bool wait_for_cancellation(std::chrono::nanoseconds timeout) const;
97
103
105 [[nodiscard]] bool shares(const CancelToken& other) const noexcept {
106 return state_ == other.state_;
107 }
108
109 protected:
111 explicit CancelToken(std::shared_ptr<State> state) noexcept : state_(std::move(state)) {}
112
115 static bool request_cancel(const std::shared_ptr<State>& state) noexcept;
116 static std::shared_ptr<State> make_state();
117
118 std::shared_ptr<State> state_;
119
120 friend class CancelSource;
121};
122
127 public:
130
131 CancelSource(const CancelSource&) = delete;
133 CancelSource(CancelSource&& other) noexcept = default;
136
138 [[nodiscard]] CancelToken token() const noexcept {
139 return token_;
140 }
141
145 bool cancel() noexcept;
146
147 [[nodiscard]] bool is_cancelled() const noexcept {
148 return token_.is_cancelled();
149 }
150
151 private:
152 CancelToken token_;
153};
154
162 public:
164
165 void cancel() noexcept {
167 }
168};
169
170} // namespace pulp::runtime
RAII registration returned by CancelToken::register_callback.
Definition cancel.hpp:50
void reset() noexcept
Unregister now. Idempotent.
friend class CancelToken
Definition cancel.hpp:69
CancelRegistration() noexcept=default
Move-only owner of a cancellation state.
Definition cancel.hpp:126
CancelSource(const CancelSource &)=delete
bool cancel() noexcept
Signal cancellation.
bool is_cancelled() const noexcept
Definition cancel.hpp:147
CancelSource & operator=(CancelSource &&other) noexcept
Cancels the state this source currently owns, then takes over other.
CancelSource(CancelSource &&other) noexcept=default
CancelToken token() const noexcept
Observer for this source. Tokens remain valid after the source dies.
Definition cancel.hpp:138
CancelSource & operator=(const CancelSource &)=delete
Definition cancel.hpp:77
bool is_cancelled() const noexcept
True once the owning source has been cancelled.
Definition cancel.hpp:84
bool shares(const CancelToken &other) const noexcept
True if both tokens observe the same underlying source.
Definition cancel.hpp:105
detail::CancelStateBase State
Definition cancel.hpp:110
static bool request_cancel(const std::shared_ptr< State > &state) noexcept
Mark the state cancelled, wake waiters, run callbacks.
bool can_be_cancelled() const noexcept
True if this token can ever become cancelled (it is bound to a source).
Definition cancel.hpp:89
static std::shared_ptr< State > make_state()
CancelRegistration register_callback(CancelCallback fn) const
Run fn when the token is cancelled.
friend class CancelSource
Definition cancel.hpp:120
std::shared_ptr< State > state_
Definition cancel.hpp:118
CancelToken(std::shared_ptr< State > state) noexcept
Definition cancel.hpp:111
CancelToken() noexcept=default
A token that can never be cancelled.
bool wait_for_cancellation(std::chrono::nanoseconds timeout) const
Block until cancelled or timeout elapses.
void cancel() noexcept
Definition cancel.hpp:165
Definition assert.hpp:29
Definition generated_event_source.hpp:33
std::function< void()> CancelCallback
Callback run when a token is cancelled.
Definition cancel.hpp:42
@ 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
STL namespace.
Public part of the shared state so is_cancelled() can inline to one load.
Definition cancel.hpp:33
std::atomic< bool > cancelled
Definition cancel.hpp:34