33 [[nodiscard]]
const char*
what() const noexcept
override {
34 return "operation was cancelled";
39struct CancellationState {
40 std::atomic<bool> cancelled{
false};
42 std::vector<std::function<void()>> callbacks;
92struct DeferredResumeContext {
93 std::vector<std::coroutine_handle<>> pending;
94 bool draining =
false;
97inline DeferredResumeContext& deferred_resume_context() noexcept {
98 thread_local DeferredResumeContext ctx;
102inline void schedule_deferred_resume(std::coroutine_handle<> h)
noexcept {
103 auto& ctx = deferred_resume_context();
107 ctx.pending.push_back(h);
114 ctx.pending.push_back(h);
123 for (std::size_t i = 0; i < ctx.pending.size(); ++i) {
124 auto coro = ctx.pending[i];
134 ctx.draining =
false;
141 DrainScope() noexcept {
142 auto& ctx = deferred_resume_context();
143 is_owner_ = !ctx.draining;
148 ~DrainScope() noexcept {
149 if (!is_owner_)
return;
150 auto& ctx = deferred_resume_context();
162 for (std::size_t i = 0; i < ctx.pending.size(); ++i) {
163 auto coro = ctx.pending[i];
172 ctx.draining =
false;
174 DrainScope(
const DrainScope&) =
delete;
175 DrainScope& operator=(
const DrainScope&) =
delete;
176 [[nodiscard]]
bool is_owner() const noexcept {
return is_owner_; }
178 bool is_owner_ =
false;
186 : state_(
std::move(s)) {}
189 return state_ && state_->cancelled.load(std::memory_order_acquire);
202 std::lock_guard lk(state_->m);
203 if (state_->cancelled.load(std::memory_order_acquire)) {
207 state_->callbacks.push_back(std::move(cb));
215 std::shared_ptr<detail::CancellationState> state_;
241 bool expected =
false;
242 if (!state_->cancelled.compare_exchange_strong(
243 expected,
true, std::memory_order_acq_rel)) {
250 detail::DrainScope drain;
251 std::vector<std::function<void()>> cbs;
253 std::lock_guard lk(state_->m);
254 cbs.swap(state_->callbacks);
256 for (
auto& c : cbs) {
257 try { c(); }
catch (...) {}
263 return state_ && state_->cancelled.load(std::memory_order_acquire);
273 if (
this != &other) {
277 state_ = std::move(other.state_);
283 std::shared_ptr<detail::CancellationState> state_;
CancellationSource(const CancellationSource &)=delete
CancellationSource()
Definition cancellation.hpp:220
CancellationSource & operator=(CancellationSource &&other) noexcept
Definition cancellation.hpp:272
~CancellationSource()
Auto-cancel on destruction — perfect for ViewModelScope.
Definition cancellation.hpp:267
CancellationSource(CancellationSource &&)=default
bool is_cancelled() const noexcept
Definition cancellation.hpp:262
CancellationSource & operator=(const CancellationSource &)=delete
void cancel()
Trigger cancellation.
Definition cancellation.hpp:239
CancellationToken token() const noexcept
Definition cancellation.hpp:222
Definition cancellation.hpp:182
void on_cancel(std::function< void()> cb)
Register a callback fired (synchronously) when source is cancelled.
Definition cancellation.hpp:199
CancellationToken(std::shared_ptr< detail::CancellationState > s)
Definition cancellation.hpp:185
void throw_if_cancelled() const
Throw OperationCancelled if cancelled. Call at safe await points.
Definition cancellation.hpp:193
bool is_cancelled() const noexcept
Definition cancellation.hpp:188
CancellationToken()=default
static CancellationToken none() noexcept
Always-cancellable empty token (useful as a default).
Definition cancellation.hpp:212
Definition cancellation.hpp:31
const char * what() const noexcept override
Definition cancellation.hpp:33
Definition async_command.hpp:118
Definition validation_key.hpp:110