ntex_util/channel/
pool.rs1use slab::Slab;
3use std::{fmt, future::Future, pin::Pin, task::Context, task::Poll};
4
5use super::{Canceled, cell::Cell};
6use crate::task::LocalWaker;
7
8pub fn new<T>() -> Pool<T> {
10 Pool(Cell::new(Slab::new()))
11}
12
13pub struct Pool<T>(Cell<Slab<Inner<T>>>);
15
16impl<T> fmt::Debug for Pool<T> {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 f.debug_struct("Pool")
19 .field("size", &self.0.get_ref().len())
20 .finish()
21 }
22}
23
24bitflags::bitflags! {
25 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
26 struct Flags: u8 {
27 const SENDER = 0b0000_0001;
28 const RECEIVER = 0b0000_0010;
29 }
30}
31
32#[derive(Debug)]
33struct Inner<T> {
34 flags: Flags,
35 value: Option<T>,
36 tx_waker: LocalWaker,
37 rx_waker: LocalWaker,
38}
39
40impl<T> Default for Pool<T> {
41 fn default() -> Pool<T> {
42 new()
43 }
44}
45
46impl<T> Pool<T> {
47 pub fn channel(&self) -> (Sender<T>, Receiver<T>) {
49 let token = self.0.get_mut().insert(Inner {
50 flags: Flags::all(),
51 value: None,
52 tx_waker: LocalWaker::default(),
53 rx_waker: LocalWaker::default(),
54 });
55
56 (
57 Sender {
58 token,
59 inner: self.0.clone(),
60 },
61 Receiver {
62 token,
63 inner: self.0.clone(),
64 },
65 )
66 }
67
68 pub fn shrink_to_fit(&self) {
70 self.0.get_mut().shrink_to_fit()
71 }
72}
73
74impl<T> Clone for Pool<T> {
75 fn clone(&self) -> Self {
76 Pool(self.0.clone())
77 }
78}
79
80#[derive(Debug)]
83pub struct Sender<T> {
84 token: usize,
85 inner: Cell<Slab<Inner<T>>>,
86}
87
88#[derive(Debug)]
91#[must_use = "futures do nothing unless polled"]
92pub struct Receiver<T> {
93 token: usize,
94 inner: Cell<Slab<Inner<T>>>,
95}
96
97#[allow(clippy::mut_from_ref)]
98fn get_inner<T>(inner: &Cell<Slab<Inner<T>>>, token: usize) -> &mut Inner<T> {
99 unsafe { inner.get_mut().get_unchecked_mut(token) }
100}
101
102impl<T> Unpin for Receiver<T> {}
104impl<T> Unpin for Sender<T> {}
105
106impl<T> Sender<T> {
107 pub fn send(self, val: T) -> Result<(), T> {
118 let inner = get_inner(&self.inner, self.token);
119 if inner.flags.contains(Flags::RECEIVER) {
120 inner.value = Some(val);
121 inner.rx_waker.wake();
122 Ok(())
123 } else {
124 Err(val)
125 }
126 }
127
128 pub fn is_canceled(&self) -> bool {
131 !get_inner(&self.inner, self.token)
132 .flags
133 .contains(Flags::RECEIVER)
134 }
135
136 pub fn poll_canceled(&self, cx: &mut Context<'_>) -> Poll<()> {
138 let inner = get_inner(&self.inner, self.token);
139
140 if inner.flags.contains(Flags::RECEIVER) {
141 inner.tx_waker.register(cx.waker());
142 Poll::Pending
143 } else {
144 Poll::Ready(())
145 }
146 }
147}
148
149impl<T> Drop for Sender<T> {
150 fn drop(&mut self) {
151 let inner = get_inner(&self.inner, self.token);
152 if inner.flags.contains(Flags::RECEIVER) {
153 inner.rx_waker.wake();
154 inner.flags.remove(Flags::SENDER);
155 } else {
156 self.inner.get_mut().remove(self.token);
157 }
158 }
159}
160
161impl<T> Receiver<T> {
162 pub fn poll_recv(&self, cx: &mut Context<'_>) -> Poll<Result<T, Canceled>> {
164 let inner = get_inner(&self.inner, self.token);
165
166 if let Some(val) = inner.value.take() {
168 return Poll::Ready(Ok(val));
169 }
170
171 if !inner.flags.contains(Flags::SENDER) {
173 Poll::Ready(Err(Canceled))
174 } else {
175 inner.rx_waker.register(cx.waker());
176 Poll::Pending
177 }
178 }
179}
180
181impl<T> Drop for Receiver<T> {
182 fn drop(&mut self) {
183 let inner = get_inner(&self.inner, self.token);
184 if inner.flags.contains(Flags::SENDER) {
185 inner.tx_waker.wake();
186 inner.flags.remove(Flags::RECEIVER);
187 } else {
188 self.inner.get_mut().remove(self.token);
189 }
190 }
191}
192
193impl<T> Future for Receiver<T> {
194 type Output = Result<T, Canceled>;
195
196 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
197 self.poll_recv(cx)
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use super::*;
204 use crate::future::lazy;
205
206 #[ntex::test]
207 async fn test_pool() {
208 let p = new();
209 p.shrink_to_fit();
210 assert!(format!("{p:?}").contains("Pool"));
211
212 let (tx, rx) = p.channel();
213 assert!(format!("{tx:?}").contains("Sender"));
214 assert!(format!("{rx:?}").contains("Receiver"));
215
216 tx.send("test").unwrap();
217 assert_eq!(rx.await.unwrap(), "test");
218 assert!(format!("{Canceled}").contains("canceled"));
219 assert!(format!("{Canceled:?}").contains("Canceled"));
220
221 let p2 = p.clone();
222 let (tx, rx) = p2.channel();
223 assert!(!tx.is_canceled());
224 drop(rx);
225 assert!(tx.is_canceled());
226 assert!(tx.send("test").is_err());
227
228 let (tx, rx) = new::<&'static str>().channel();
229 drop(tx);
230 assert!(rx.await.is_err());
231
232 let (tx, mut rx) = new::<&'static str>().channel();
233 assert_eq!(lazy(|cx| Pin::new(&mut rx).poll(cx)).await, Poll::Pending);
234 tx.send("test").unwrap();
235 assert_eq!(rx.await.unwrap(), "test");
236
237 let (tx, mut rx) = new::<&'static str>().channel();
238 assert_eq!(lazy(|cx| Pin::new(&mut rx).poll(cx)).await, Poll::Pending);
239 drop(tx);
240 assert!(rx.await.is_err());
241
242 let (mut tx, rx) = new::<&'static str>().channel();
243 assert!(!tx.is_canceled());
244 assert_eq!(
245 lazy(|cx| Pin::new(&mut tx).poll_canceled(cx)).await,
246 Poll::Pending
247 );
248 drop(rx);
249 assert!(tx.is_canceled());
250 assert_eq!(
251 lazy(|cx| Pin::new(&mut tx).poll_canceled(cx)).await,
252 Poll::Ready(())
253 );
254
255 let p = Pool::default();
256 let (tx, rx) = p.channel();
257 tx.send("test").unwrap();
258 assert_eq!(rx.await.unwrap(), "test");
259 }
260}