Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
cancellation_token.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
13
14#include <atomic>
15#include <functional>
16#include <memory>
17#include <mutex>
18#include <vector>
19
20namespace kcenon::thread {
21
31private:
32 // Private implementation to allow copying/moving the token
33 struct token_state {
34 std::atomic<bool> is_cancelled{false};
35 std::vector<std::function<void()>> callbacks;
36 std::mutex callback_mutex;
37 };
38
39 std::shared_ptr<token_state> state_;
40
41 // Private constructor that takes a state
42 explicit cancellation_token(std::shared_ptr<token_state> state)
43 : state_(std::move(state)) {}
44
45public:
46 // Default constructor creates a new token
47 cancellation_token() : state_(std::make_shared<token_state>()) {}
48
49 // Allow copy/move operations
54
60 return cancellation_token();
61 }
62
70 static cancellation_token create_linked(std::initializer_list<cancellation_token> tokens) {
71 auto new_token = create();
72 auto new_state_weak = std::weak_ptr<token_state>(new_token.state_);
73
74 for (const auto& token : tokens) {
75 auto token_copy = token;
76 token_copy.register_callback([new_state_weak]() {
77 if (auto state = new_state_weak.lock()) {
78 // Directly set the cancelled flag and invoke callbacks
79 std::vector<std::function<void()>> callbacks_to_invoke;
80
81 {
82 std::lock_guard<std::mutex> lock(state->callback_mutex);
83 bool was_cancelled = state->is_cancelled.exchange(true, std::memory_order_release);
84 if (!was_cancelled) {
85 callbacks_to_invoke = std::move(state->callbacks);
86 state->callbacks.clear();
87 }
88 }
89
90 for (const auto& callback : callbacks_to_invoke) {
91 callback();
92 }
93 }
94 });
95 }
96
97 return new_token;
98 }
99
111 void cancel() {
112 std::vector<std::function<void()>> callbacks_to_invoke;
113
114 {
115 std::lock_guard<std::mutex> lock(state_->callback_mutex);
116 bool was_cancelled = state_->is_cancelled.exchange(true, std::memory_order_release);
117 if (!was_cancelled) {
118 // Move callbacks to local vector to avoid holding lock during invocation
119 callbacks_to_invoke = std::move(state_->callbacks);
120 state_->callbacks.clear();
121 }
122 }
123
124 // Invoke callbacks outside the lock to prevent deadlock
125 for (const auto& callback : callbacks_to_invoke) {
126 callback();
127 }
128 }
129
139 [[nodiscard]] bool is_cancelled() const {
140 return state_->is_cancelled.load(std::memory_order_acquire);
141 }
142
148 [[nodiscard]] common::VoidResult check_cancelled() const {
149 if (is_cancelled()) {
151 }
152 return common::ok();
153 }
154
167 void register_callback(std::function<void()> callback) {
168 std::unique_lock<std::mutex> lock(state_->callback_mutex);
169
170 // Check cancellation state while holding the lock
171 if (state_->is_cancelled.load(std::memory_order_acquire)) {
172 lock.unlock();
173 callback();
174 return;
175 }
176
177 // Add callback while still holding the lock
178 state_->callbacks.push_back(std::move(callback));
179 }
180};
181
182} // namespace kcenon::thread
Provides a mechanism for cooperative cancellation of operations.
cancellation_token(std::shared_ptr< token_state > state)
cancellation_token(cancellation_token &&)=default
common::VoidResult check_cancelled() const
Checks if the token has been canceled and returns an error result.
void cancel()
Cancels the operation.
void register_callback(std::function< void()> callback)
Registers a callback to be invoked when the token is canceled.
cancellation_token(const cancellation_token &)=default
static cancellation_token create_linked(std::initializer_list< cancellation_token > tokens)
Creates a linked token that is canceled when any of the parent tokens are canceled.
static cancellation_token create()
Creates a new cancellation token.
cancellation_token & operator=(cancellation_token &&)=default
bool is_cancelled() const
Checks if the token has been canceled.
cancellation_token & operator=(const cancellation_token &)=default
std::shared_ptr< token_state > state_
@ callback
Call user callback for custom decision.
Error codes and utilities for the thread system.
Core threading foundation of the thread system library.
Definition thread_impl.h:17
common::VoidResult make_error_result(error_code code, const std::string &message="")
Create a common::VoidResult error from a thread::error_code.
STL namespace.
std::vector< std::function< void()> > callbacks