ntex_util/channel/
mpsc.rs1use std::collections::VecDeque;
3use std::future::poll_fn;
4use std::{fmt, panic::UnwindSafe, pin::Pin, task::Context, task::Poll};
5
6use futures_core::{FusedStream, Stream};
7
8use super::cell::Cell;
9use crate::task::LocalWaker;
10
11pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
13 let shared = Cell::new(Shared {
14 has_receiver: true,
15 buffer: VecDeque::new(),
16 blocked_recv: LocalWaker::new(),
17 closed: LocalWaker::new(),
18 });
19 let sender = Sender {
20 shared: shared.clone(),
21 };
22 let receiver = Receiver { shared };
23 (sender, receiver)
24}
25
26#[derive(Debug)]
27struct Shared<T> {
28 buffer: VecDeque<T>,
29 blocked_recv: LocalWaker,
30 closed: LocalWaker,
31 has_receiver: bool,
32}
33
34impl<T> Shared<T> {
35 fn close(&mut self) {
36 self.has_receiver = false;
37 self.blocked_recv.wake();
38 self.closed.wake();
39 }
40}
41
42#[derive(Debug)]
46pub struct Sender<T> {
47 shared: Cell<Shared<T>>,
48}
49
50impl<T> Unpin for Sender<T> {}
51
52impl<T> Sender<T> {
53 pub fn send(&self, item: T) -> Result<(), SendError<T>> {
55 let shared = self.shared.get_mut();
56 if !shared.has_receiver {
57 return Err(SendError(item)); }
59 shared.buffer.push_back(item);
60 shared.blocked_recv.wake();
61 Ok(())
62 }
63
64 pub fn close(&self) {
70 self.shared.get_mut().close();
71 }
72
73 pub fn is_closed(&self) -> bool {
75 self.shared.strong_count() == 1 || !self.shared.get_ref().has_receiver
76 }
77
78 pub fn poll_closed(&self, cx: &mut Context<'_>) -> Poll<()> {
83 let shared = self.shared.get_mut();
84 if shared.has_receiver {
85 shared.closed.register(cx.waker());
86 Poll::Pending
87 } else {
88 Poll::Ready(())
89 }
90 }
91
92 pub async fn closed(&self) {
96 poll_fn(|cx| self.poll_closed(cx)).await;
97 }
98}
99
100impl<T> Clone for Sender<T> {
101 fn clone(&self) -> Self {
102 Sender {
103 shared: self.shared.clone(),
104 }
105 }
106}
107
108impl<T> Drop for Sender<T> {
109 fn drop(&mut self) {
110 let count = self.shared.strong_count();
111 let shared = self.shared.get_mut();
112
113 if shared.has_receiver && count == 2 {
115 shared.blocked_recv.wake();
117 }
118 }
119}
120
121#[derive(Debug)]
125pub struct Receiver<T> {
126 shared: Cell<Shared<T>>,
127}
128
129impl<T> Receiver<T> {
130 pub fn sender(&self) -> Sender<T> {
132 Sender {
133 shared: self.shared.clone(),
134 }
135 }
136
137 pub fn close(&self) {
142 self.shared.get_mut().close();
143 }
144
145 pub fn is_closed(&self) -> bool {
147 self.shared.strong_count() == 1 || !self.shared.get_ref().has_receiver
148 }
149
150 pub async fn recv(&self) -> Option<T> {
155 poll_fn(|cx| self.poll_recv(cx)).await
156 }
157
158 pub fn poll_recv(&self, cx: &mut Context<'_>) -> Poll<Option<T>> {
163 let shared = self.shared.get_mut();
164
165 if let Some(msg) = shared.buffer.pop_front() {
166 Poll::Ready(Some(msg))
167 } else if shared.has_receiver {
168 shared.blocked_recv.register(cx.waker());
169 if self.shared.strong_count() == 1 {
170 Poll::Ready(None)
173 } else {
174 Poll::Pending
175 }
176 } else {
177 Poll::Ready(None)
178 }
179 }
180}
181
182impl<T> Unpin for Receiver<T> {}
183
184impl<T> Stream for Receiver<T> {
185 type Item = T;
186
187 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
188 self.poll_recv(cx)
189 }
190}
191
192impl<T> FusedStream for Receiver<T> {
193 fn is_terminated(&self) -> bool {
196 self.is_closed() && self.shared.get_ref().buffer.is_empty()
197 }
198}
199
200impl<T> UnwindSafe for Receiver<T> {}
201
202impl<T> Drop for Receiver<T> {
203 fn drop(&mut self) {
204 let shared = self.shared.get_mut();
205 shared.has_receiver = false;
206 let buffer = std::mem::take(&mut shared.buffer);
207 shared.closed.wake();
208
209 drop(buffer);
211 }
212}
213
214pub struct SendError<T>(T);
217
218impl<T> std::error::Error for SendError<T> {}
219
220impl<T> fmt::Debug for SendError<T> {
221 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
222 fmt.debug_tuple("SendError").field(&"...").finish()
223 }
224}
225
226impl<T> fmt::Display for SendError<T> {
227 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
228 write!(fmt, "send failed because receiver is gone")
229 }
230}
231
232impl<T> SendError<T> {
233 pub fn into_inner(self) -> T {
235 self.0
236 }
237}
238
239#[cfg(test)]
240mod tests {
241 use super::*;
242 use crate::{future::lazy, future::stream_recv};
243
244 #[ntex::test]
250 async fn test_mpsc() {
251 let (tx, mut rx) = channel();
252 assert!(format!("{tx:?}").contains("Sender"));
253 assert!(format!("{rx:?}").contains("Receiver"));
254
255 tx.send("test").unwrap();
256 assert_eq!(stream_recv(&mut rx).await.unwrap(), "test");
257
258 let tx2 = tx.clone();
259 tx2.send("test2").unwrap();
260 assert_eq!(stream_recv(&mut rx).await.unwrap(), "test2");
261
262 assert_eq!(
263 lazy(|cx| Pin::new(&mut rx).poll_next(cx)).await,
264 Poll::Pending
265 );
266 drop(tx2);
267 assert_eq!(
268 lazy(|cx| Pin::new(&mut rx).poll_next(cx)).await,
269 Poll::Pending
270 );
271 drop(tx);
272
273 let (tx, mut rx) = channel::<String>();
274 tx.close();
275 assert_eq!(stream_recv(&mut rx).await, None);
276
277 let (tx, rx) = channel();
278 tx.send("test").unwrap();
279 drop(rx);
280 assert!(tx.send("test").is_err());
281
282 let (tx, _) = channel();
283 let tx2 = tx.clone();
284 tx.close();
285 assert!(tx.send("test").is_err());
286 assert!(tx2.send("test").is_err());
287
288 let err = SendError("test");
289 assert!(format!("{err:?}").contains("SendError"));
290 assert!(format!("{err}").contains("send failed because receiver is gone"));
291 assert_eq!(err.into_inner(), "test");
292 }
293
294 #[ntex::test]
300 async fn test_close() {
301 let (tx, rx) = channel::<()>();
302 assert!(!tx.is_closed());
303 assert!(!rx.is_closed());
304 assert!(!rx.is_terminated());
305
306 tx.close();
307 assert!(tx.is_closed());
308 assert!(rx.is_closed());
309 assert!(rx.is_terminated());
310
311 let (tx, rx) = channel::<()>();
312 assert_eq!(lazy(|cx| rx.poll_recv(cx)).await, Poll::Pending);
313 assert!(rx.shared.get_ref().blocked_recv.is_set());
314 rx.close();
315 assert!(tx.is_closed());
316 assert!(!rx.shared.get_ref().blocked_recv.is_set());
317 assert_eq!(lazy(|cx| rx.poll_recv(cx)).await, Poll::Ready(None));
318
319 let (tx, rx) = channel::<()>();
320 drop(tx);
321 assert!(rx.is_closed());
322 assert!(rx.is_terminated());
323 let _tx = rx.sender();
324 assert!(!rx.is_closed());
325 assert!(!rx.is_terminated());
326 }
327
328 #[ntex::test]
334 async fn test_poll_closed() {
335 let (tx, rx) = channel::<()>();
336 assert_eq!(lazy(|cx| tx.poll_closed(cx)).await, Poll::Pending);
337 assert!(tx.shared.get_ref().closed.is_set());
338 drop(rx);
339 assert!(!tx.shared.get_ref().closed.is_set());
340 assert_eq!(lazy(|cx| tx.poll_closed(cx)).await, Poll::Ready(()));
341 tx.closed().await;
342
343 let (tx, rx) = channel::<()>();
344 assert_eq!(lazy(|cx| tx.poll_closed(cx)).await, Poll::Pending);
345 rx.close();
346 assert!(!tx.shared.get_ref().closed.is_set());
347 tx.closed().await;
348
349 let (tx, _rx) = channel::<()>();
350 let tx2 = tx.clone();
351 assert_eq!(lazy(|cx| tx2.poll_closed(cx)).await, Poll::Pending);
352 tx.close();
353 assert!(!tx.shared.get_ref().closed.is_set());
354 tx2.closed().await;
355 }
356
357 #[test]
363 fn test_drop_receiver_reentrant_send() {
364 use std::rc::Rc;
365
366 struct Msg(Option<Sender<Msg>>, Rc<std::cell::Cell<usize>>);
367
368 impl Drop for Msg {
369 fn drop(&mut self) {
370 self.1.set(self.1.get() + 1);
371 if let Some(tx) = self.0.take() {
372 assert!(tx.send(Msg(None, self.1.clone())).is_err());
373 }
374 }
375 }
376
377 let drops = Rc::new(std::cell::Cell::new(0));
378 let (tx, rx) = channel();
379 for _ in 0..4 {
380 tx.send(Msg(Some(tx.clone()), drops.clone())).unwrap();
381 }
382 drop(rx);
383 assert_eq!(drops.get(), 8);
384 assert!(tx.is_closed());
385 }
386
387 #[ntex::test]
393 async fn test_fused_drains_buffer() {
394 let (tx, mut rx) = channel();
395 tx.send(1).unwrap();
396 tx.send(2).unwrap();
397 drop(tx);
398
399 assert!(!rx.is_terminated());
400 assert_eq!(stream_recv(&mut rx).await, Some(1));
401 assert_eq!(stream_recv(&mut rx).await, Some(2));
402 assert!(rx.is_terminated());
403 assert_eq!(stream_recv(&mut rx).await, None);
404
405 let (tx, mut rx) = channel();
406 tx.send(1).unwrap();
407 rx.close();
408 assert!(!rx.is_terminated());
409 assert_eq!(stream_recv(&mut rx).await, Some(1));
410 assert!(rx.is_terminated());
411 }
412
413 #[ntex::test]
418 async fn test_mpsc_recv() {
419 let (tx, rx) = channel();
420 tx.send(1).unwrap();
421 assert_eq!(rx.recv().await, Some(1));
422 drop(tx);
423 assert_eq!(rx.recv().await, None);
424 }
425}