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
30class cancellation_token {
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);
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
107 void cancel() {
108 std::vector<std::function<void()>> callbacks_to_invoke;
109
110 {
111 std::lock_guard<std::mutex> lock(state_->callback_mutex);
112 bool was_cancelled = state_->is_cancelled.exchange(true);
113 if (!was_cancelled) {
114 // Move callbacks to local vector to avoid holding lock during invocation
115 callbacks_to_invoke = std::move(state_->callbacks);
116 state_->callbacks.clear();
117 }
118 }
119
120 // Invoke callbacks outside the lock to prevent deadlock
121 for (const auto& callback : callbacks_to_invoke) {
122 callback();
123 }
124 }
125
130 [[nodiscard]] bool is_cancelled() const {
131 return state_->is_cancelled.load();
132 }
133
139 [[nodiscard]] common::VoidResult check_cancelled() const {
140 if (is_cancelled()) {
142 }
143 return common::ok();
144 }
145
154 void register_callback(std::function<void()> callback) {
155 std::unique_lock<std::mutex> lock(state_->callback_mutex);
156
157 // Check cancellation state while holding the lock
158 if (state_->is_cancelled.load()) {
159 lock.unlock();
160 callback();
161 return;
162 }
163
164 // Add callback while still holding the lock
165 state_->callbacks.push_back(std::move(callback));
166 }
167};
168
169} // 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