Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
cancellable_future.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
17
18#include <chrono>
19#include <future>
20#include <optional>
21
22namespace kcenon::thread {
23
55template<typename R>
57public:
58 using value_type = R;
59
66 cancellable_future(std::future<R> future, cancellation_token token)
67 : future_(std::move(future))
68 , token_(std::move(token))
69 {}
70
71 // Destructor
73
74 // Delete copy operations
77
78 // Allow move operations
80 cancellable_future& operator=(cancellable_future&&) noexcept = default;
81
91 [[nodiscard]] auto get() -> common::Result<R> {
92 if (token_.is_cancelled()) {
93 return make_error_result<R>(error_code::operation_canceled);
94 }
95 try {
96 return common::Result<R>::ok(future_.get());
97 } catch (const std::exception& e) {
99 } catch (...) {
100 return make_error_result<R>(error_code::unknown_error, "Unknown exception in future");
101 }
102 }
103
114 [[nodiscard]] auto get_for(std::chrono::milliseconds timeout)
115 -> common::Result<std::optional<R>>
116 {
117 if (token_.is_cancelled()) {
119 }
120
121 auto status = future_.wait_for(timeout);
122 if (status == std::future_status::ready) {
123 try {
124 return common::Result<std::optional<R>>::ok(future_.get());
125 } catch (const std::exception& e) {
128 } catch (...) {
130 error_code::unknown_error, "Unknown exception in future");
131 }
132 }
133 return common::Result<std::optional<R>>::ok(std::nullopt);
134 }
135
141 [[nodiscard]] auto is_ready() const -> bool {
142 return future_.wait_for(std::chrono::seconds(0)) ==
143 std::future_status::ready;
144 }
145
151 [[nodiscard]] auto is_cancelled() const -> bool {
152 return token_.is_cancelled();
153 }
154
162 void cancel() {
163 token_.cancel();
164 }
165
171 [[nodiscard]] auto valid() const -> bool {
172 return future_.valid();
173 }
174
180 void wait() const {
181 future_.wait();
182 }
183
190 template<typename Rep, typename Period>
191 [[nodiscard]] auto wait_for(const std::chrono::duration<Rep, Period>& timeout) const
192 -> std::future_status
193 {
194 return future_.wait_for(timeout);
195 }
196
202 [[nodiscard]] auto get_token() const -> cancellation_token {
203 return token_;
204 }
205
206private:
207 mutable std::future<R> future_;
209};
210
214template<>
216public:
217 using value_type = void;
218
219 cancellable_future(std::future<void> future, cancellation_token token)
220 : future_(std::move(future))
221 , token_(std::move(token))
222 {}
223
225
229 cancellable_future& operator=(cancellable_future&&) noexcept = default;
230
231 [[nodiscard]] auto get() -> common::VoidResult {
232 if (token_.is_cancelled()) {
233 return make_error_result(error_code::operation_canceled);
234 }
235 try {
236 future_.get();
237 return common::ok();
238 } catch (const std::exception& e) {
240 } catch (...) {
241 return make_error_result(error_code::unknown_error, "Unknown exception in future");
242 }
243 }
244
245 [[nodiscard]] auto get_for(std::chrono::milliseconds timeout) -> common::Result<bool> {
246 if (token_.is_cancelled()) {
248 }
249
250 auto status = future_.wait_for(timeout);
251 if (status == std::future_status::ready) {
252 try {
253 future_.get();
254 return common::Result<bool>::ok(true);
255 } catch (const std::exception& e) {
257 } catch (...) {
258 return make_error_result<bool>(error_code::unknown_error, "Unknown exception in future");
259 }
260 }
261 return common::Result<bool>::ok(false);
262 }
263
264 [[nodiscard]] auto is_ready() const -> bool {
265 return future_.wait_for(std::chrono::seconds(0)) ==
266 std::future_status::ready;
267 }
268
269 [[nodiscard]] auto is_cancelled() const -> bool {
270 return token_.is_cancelled();
271 }
272
273 void cancel() {
274 token_.cancel();
275 }
276
277 [[nodiscard]] auto valid() const -> bool {
278 return future_.valid();
279 }
280
281 void wait() const {
282 future_.wait();
283 }
284
285 template<typename Rep, typename Period>
286 [[nodiscard]] auto wait_for(const std::chrono::duration<Rep, Period>& timeout) const
287 -> std::future_status
288 {
289 return future_.wait_for(timeout);
290 }
291
292 [[nodiscard]] auto get_token() const -> cancellation_token {
293 return token_;
294 }
295
296private:
297 mutable std::future<void> future_;
299};
300
301} // namespace kcenon::thread
auto get_token() const -> cancellation_token
cancellable_future & operator=(const cancellable_future &)=delete
auto get_for(std::chrono::milliseconds timeout) -> common::Result< bool >
cancellable_future(std::future< void > future, cancellation_token token)
cancellable_future(const cancellable_future &)=delete
cancellable_future(cancellable_future &&) noexcept=default
auto wait_for(const std::chrono::duration< Rep, Period > &timeout) const -> std::future_status
A future wrapper that supports cancellation.
auto wait_for(const std::chrono::duration< Rep, Period > &timeout) const -> std::future_status
Wait for the result with timeout.
auto get() -> common::Result< R >
Wait for and retrieve the result.
auto is_cancelled() const -> bool
Check if the operation was cancelled.
void wait() const
Wait for the result to become ready.
cancellable_future(cancellable_future &&) noexcept=default
cancellable_future(const cancellable_future &)=delete
auto valid() const -> bool
Check if the future is valid.
void cancel()
Request cancellation of the operation.
cancellable_future & operator=(const cancellable_future &)=delete
cancellable_future(std::future< R > future, cancellation_token token)
Construct a cancellable_future.
auto is_ready() const -> bool
Check if the result is ready.
auto get_token() const -> cancellation_token
Get the cancellation token.
auto get_for(std::chrono::milliseconds timeout) -> common::Result< std::optional< R > >
Wait for the result with timeout.
Provides a mechanism for cooperative cancellation of operations.
void cancel()
Cancels the operation.
bool is_cancelled() const
Checks if the token has been canceled.
Implementation of a cancellation token for cooperative cancellation.
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.