qubit_retry/executor/attempt_cancel_token.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! Cooperative cancellation token for blocking attempts.
11//!
12
13use std::sync::Arc;
14use std::sync::atomic::{
15 AtomicBool,
16 Ordering,
17};
18
19/// Cooperative cancellation token passed to blocking timeout attempts.
20///
21/// The retry executor marks the token as cancelled when
22/// [`crate::Retry::run_in_worker`] stops waiting for a timed-out worker thread.
23/// The worker must check [`AttemptCancelToken::is_cancelled`] and return on its
24/// own; Rust threads cannot be safely killed by the executor.
25#[derive(Debug, Clone, Default)]
26pub struct AttemptCancelToken {
27 /// Shared cancellation flag.
28 cancelled: Arc<AtomicBool>,
29}
30
31impl AttemptCancelToken {
32 /// Creates a fresh non-cancelled token.
33 ///
34 /// # Returns
35 /// A token whose cancellation flag is initially `false`.
36 #[inline]
37 pub fn new() -> Self {
38 Self::default()
39 }
40
41 /// Marks this token as cancelled.
42 ///
43 /// # Parameters
44 /// This method has no parameters.
45 ///
46 /// # Side Effects
47 /// Sets the shared cancellation flag. Clones of this token observe the same
48 /// flag.
49 #[inline]
50 pub fn cancel(&self) {
51 self.cancelled.store(true, Ordering::SeqCst);
52 }
53
54 /// Returns whether cancellation has been requested.
55 ///
56 /// # Returns
57 /// `true` after the executor or another holder calls
58 /// [`AttemptCancelToken::cancel`].
59 #[inline]
60 pub fn is_cancelled(&self) -> bool {
61 self.cancelled.load(Ordering::SeqCst)
62 }
63}