wasm_actor_bridge/
cancel.rs1#[cfg(not(target_arch = "wasm32"))]
10mod native_impl {
11 use std::future::Future;
12 use std::pin::Pin;
13 use std::sync::Arc;
14 use std::sync::atomic::{AtomicBool, Ordering};
15 use std::task::{Context, Poll};
16
17 #[derive(Clone)]
21 pub struct CancellationToken {
22 cancelled: Arc<AtomicBool>,
23 }
24
25 pub struct CancelGuard {
27 cancelled: Arc<AtomicBool>,
28 }
29
30 impl CancellationToken {
31 pub fn new() -> (Self, CancelGuard) {
35 let cancelled = Arc::new(AtomicBool::new(false));
36 (
37 Self {
38 cancelled: Arc::clone(&cancelled),
39 },
40 CancelGuard { cancelled },
41 )
42 }
43
44 pub fn is_cancelled(&self) -> bool {
46 self.cancelled.load(Ordering::Acquire)
47 }
48
49 pub fn cancelled(&self) -> CancelledFuture {
51 CancelledFuture {
52 token: self.clone(),
53 }
54 }
55 }
56
57 impl Drop for CancelGuard {
58 fn drop(&mut self) {
59 self.cancelled.store(true, Ordering::Release);
60 }
61 }
62
63 pub struct CancelledFuture {
65 token: CancellationToken,
66 }
67
68 impl Future for CancelledFuture {
69 type Output = ();
70
71 fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
72 if self.token.is_cancelled() {
73 Poll::Ready(())
74 } else {
75 Poll::Pending
76 }
77 }
78 }
79}
80
81#[cfg(not(target_arch = "wasm32"))]
82pub use native_impl::*;
83
84#[cfg(target_arch = "wasm32")]
87mod wasm_impl {
88 use std::cell::Cell;
89 use std::future::Future;
90 use std::pin::Pin;
91 use std::rc::Rc;
92 use std::task::{Context, Poll, Waker};
93
94 #[derive(Clone)]
98 pub struct CancellationToken {
99 inner: Rc<TokenInner>,
100 }
101
102 struct TokenInner {
103 cancelled: Cell<bool>,
104 waker: Cell<Option<Waker>>,
105 }
106
107 pub struct CancelGuard {
109 inner: Rc<TokenInner>,
110 }
111
112 impl CancellationToken {
113 pub fn new() -> (Self, CancelGuard) {
117 let inner = Rc::new(TokenInner {
118 cancelled: Cell::new(false),
119 waker: Cell::new(None),
120 });
121 let token = Self {
122 inner: Rc::clone(&inner),
123 };
124 let guard = CancelGuard { inner };
125 (token, guard)
126 }
127
128 pub fn is_cancelled(&self) -> bool {
130 self.inner.cancelled.get()
131 }
132
133 pub fn cancelled(&self) -> CancelledFuture {
135 CancelledFuture {
136 token: self.clone(),
137 }
138 }
139 }
140
141 impl Drop for CancelGuard {
142 fn drop(&mut self) {
143 self.inner.cancelled.set(true);
144 if let Some(waker) = self.inner.waker.take() {
145 waker.wake();
146 }
147 }
148 }
149
150 pub struct CancelledFuture {
152 token: CancellationToken,
153 }
154
155 impl Future for CancelledFuture {
156 type Output = ();
157
158 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
159 if self.token.is_cancelled() {
160 Poll::Ready(())
161 } else {
162 self.token.inner.waker.set(Some(cx.waker().clone()));
163 Poll::Pending
164 }
165 }
166 }
167}
168
169#[cfg(target_arch = "wasm32")]
170pub use wasm_impl::*;