matrixcode_core/
cancel.rs1use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
2
3pub struct CancellationToken {
6 cancelled: Arc<AtomicBool>,
7}
8
9impl CancellationToken {
10 pub fn new() -> Self {
12 Self {
13 cancelled: Arc::new(AtomicBool::new(false)),
14 }
15 }
16
17 pub fn cancel(&self) {
19 self.cancelled.store(true, Ordering::SeqCst);
20 }
21
22 pub fn is_cancelled(&self) -> bool {
24 self.cancelled.load(Ordering::SeqCst)
25 }
26
27 pub fn reset(&self) {
30 self.cancelled.store(false, Ordering::SeqCst);
31 }
32}
33
34impl Default for CancellationToken {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40impl Clone for CancellationToken {
41 fn clone(&self) -> Self {
42 Self {
43 cancelled: self.cancelled.clone(),
44 }
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn test_cancel() {
54 let token = CancellationToken::new();
55 assert!(!token.is_cancelled());
56 token.cancel();
57 assert!(token.is_cancelled());
58 }
59
60 #[test]
61 fn test_clone_cancel() {
62 let token = CancellationToken::new();
63 let clone = token.clone();
64 clone.cancel();
65 assert!(token.is_cancelled());
66 assert!(clone.is_cancelled());
67 }
68
69 #[test]
70 fn test_multiple_clones() {
71 let token = CancellationToken::new();
72 let clone1 = token.clone();
73 let clone2 = clone1.clone();
74
75 assert!(!token.is_cancelled());
76 assert!(!clone1.is_cancelled());
77 assert!(!clone2.is_cancelled());
78
79 token.cancel();
80
81 assert!(token.is_cancelled());
82 assert!(clone1.is_cancelled());
83 assert!(clone2.is_cancelled());
84 }
85
86 #[test]
87 fn test_reset() {
88 let token = CancellationToken::new();
89 token.cancel();
90 assert!(token.is_cancelled());
91 token.reset();
92 assert!(!token.is_cancelled());
93 }
94
95 #[test]
96 fn test_reset_visible_in_clones() {
97 let token = CancellationToken::new();
98 let clone = token.clone();
99
100 token.cancel();
101 assert!(clone.is_cancelled());
102
103 clone.reset();
104 assert!(!token.is_cancelled());
105 assert!(!clone.is_cancelled());
106 }
107
108 #[test]
109 fn test_cancel_reset_cycle() {
110 let token = CancellationToken::new();
111
112 token.cancel();
114 assert!(token.is_cancelled());
115 token.reset();
116 assert!(!token.is_cancelled());
117
118 token.cancel();
120 assert!(token.is_cancelled());
121 token.reset();
122 assert!(!token.is_cancelled());
123
124 token.cancel();
126 assert!(token.is_cancelled());
127 }
128}