1 use crate::sync::CancellationToken;
2 
3 use loom::{future::block_on, thread};
4 use tokio_test::assert_ok;
5 
6 #[test]
cancel_token()7 fn cancel_token() {
8     loom::model(|| {
9         let token = CancellationToken::new();
10         let token1 = token.clone();
11 
12         let th1 = thread::spawn(move || {
13             block_on(async {
14                 token1.cancelled().await;
15             });
16         });
17 
18         let th2 = thread::spawn(move || {
19             token.cancel();
20         });
21 
22         assert_ok!(th1.join());
23         assert_ok!(th2.join());
24     });
25 }
26 
27 #[test]
cancel_with_child()28 fn cancel_with_child() {
29     loom::model(|| {
30         let token = CancellationToken::new();
31         let token1 = token.clone();
32         let token2 = token.clone();
33         let child_token = token.child_token();
34 
35         let th1 = thread::spawn(move || {
36             block_on(async {
37                 token1.cancelled().await;
38             });
39         });
40 
41         let th2 = thread::spawn(move || {
42             token2.cancel();
43         });
44 
45         let th3 = thread::spawn(move || {
46             block_on(async {
47                 child_token.cancelled().await;
48             });
49         });
50 
51         assert_ok!(th1.join());
52         assert_ok!(th2.join());
53         assert_ok!(th3.join());
54     });
55 }
56 
57 #[test]
drop_token_no_child()58 fn drop_token_no_child() {
59     loom::model(|| {
60         let token = CancellationToken::new();
61         let token1 = token.clone();
62         let token2 = token.clone();
63 
64         let th1 = thread::spawn(move || {
65             drop(token1);
66         });
67 
68         let th2 = thread::spawn(move || {
69             drop(token2);
70         });
71 
72         let th3 = thread::spawn(move || {
73             drop(token);
74         });
75 
76         assert_ok!(th1.join());
77         assert_ok!(th2.join());
78         assert_ok!(th3.join());
79     });
80 }
81 
82 #[test]
drop_token_with_childs()83 fn drop_token_with_childs() {
84     loom::model(|| {
85         let token1 = CancellationToken::new();
86         let child_token1 = token1.child_token();
87         let child_token2 = token1.child_token();
88 
89         let th1 = thread::spawn(move || {
90             drop(token1);
91         });
92 
93         let th2 = thread::spawn(move || {
94             drop(child_token1);
95         });
96 
97         let th3 = thread::spawn(move || {
98             drop(child_token2);
99         });
100 
101         assert_ok!(th1.join());
102         assert_ok!(th2.join());
103         assert_ok!(th3.join());
104     });
105 }
106 
107 #[test]
drop_and_cancel_token()108 fn drop_and_cancel_token() {
109     loom::model(|| {
110         let token1 = CancellationToken::new();
111         let token2 = token1.clone();
112         let child_token = token1.child_token();
113 
114         let th1 = thread::spawn(move || {
115             drop(token1);
116         });
117 
118         let th2 = thread::spawn(move || {
119             token2.cancel();
120         });
121 
122         let th3 = thread::spawn(move || {
123             drop(child_token);
124         });
125 
126         assert_ok!(th1.join());
127         assert_ok!(th2.join());
128         assert_ok!(th3.join());
129     });
130 }
131 
132 #[test]
cancel_parent_and_child()133 fn cancel_parent_and_child() {
134     loom::model(|| {
135         let token1 = CancellationToken::new();
136         let token2 = token1.clone();
137         let child_token = token1.child_token();
138 
139         let th1 = thread::spawn(move || {
140             drop(token1);
141         });
142 
143         let th2 = thread::spawn(move || {
144             token2.cancel();
145         });
146 
147         let th3 = thread::spawn(move || {
148             child_token.cancel();
149         });
150 
151         assert_ok!(th1.join());
152         assert_ok!(th2.join());
153         assert_ok!(th3.join());
154     });
155 }
156