1use 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, wake};
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
34fn close<T>(shared: &Cell<Shared<T>>) {
35 let (recv, closed) = {
36 let shared = shared.get_mut();
37 shared.has_receiver = false;
38 (shared.blocked_recv.take_local(), shared.closed.take_local())
39 };
40 wake(recv);
41 wake(closed);
42}
43
44#[derive(Debug)]
48pub struct Sender<T> {
49 shared: Cell<Shared<T>>,
50}
51
52impl<T> Unpin for Sender<T> {}
53
54impl<T> Sender<T> {
55 pub fn send(&self, item: T) -> Result<(), SendError<T>> {
57 let waker = {
58 let shared = self.shared.get_mut();
59 if !shared.has_receiver {
60 return Err(SendError(item)); }
62 shared.buffer.push_back(item);
63 shared.blocked_recv.take_local()
64 };
65 wake(waker);
66 Ok(())
67 }
68
69 pub fn close(&self) {
75 close(&self.shared);
76 }
77
78 pub fn is_closed(&self) -> bool {
80 self.shared.strong_count() == 1 || !self.shared.get_ref().has_receiver
81 }
82
83 pub fn poll_closed(&self, cx: &mut Context<'_>) -> Poll<()> {
88 if !self.shared.get_ref().has_receiver {
89 return Poll::Ready(());
90 }
91 LocalWaker::register_in(|| &self.shared.get_ref().closed, cx.waker());
92
93 if self.shared.get_ref().has_receiver {
95 Poll::Pending
96 } else {
97 Poll::Ready(())
98 }
99 }
100
101 pub async fn closed(&self) {
106 poll_fn(|cx| self.poll_closed(cx)).await;
107 }
108}
109
110impl<T> Clone for Sender<T> {
111 fn clone(&self) -> Self {
112 Sender {
113 shared: self.shared.clone(),
114 }
115 }
116}
117
118impl<T> Drop for Sender<T> {
119 fn drop(&mut self) {
120 let count = self.shared.strong_count();
121 let waker = {
122 let shared = self.shared.get_mut();
123
124 if shared.has_receiver && count == 2 {
126 shared.has_receiver = false;
129 shared.blocked_recv.take_local()
130 } else {
131 None
132 }
133 };
134 wake(waker);
135 }
136}
137
138#[derive(Debug)]
150pub struct Receiver<T> {
151 shared: Cell<Shared<T>>,
152}
153
154impl<T> Receiver<T> {
155 pub fn sender(&self) -> Sender<T> {
160 Sender {
161 shared: self.shared.clone(),
162 }
163 }
164
165 pub fn close(&self) {
170 close(&self.shared);
171 }
172
173 pub fn is_closed(&self) -> bool {
175 self.shared.strong_count() == 1 || !self.shared.get_ref().has_receiver
176 }
177
178 pub async fn recv(&self) -> Option<T> {
185 poll_fn(|cx| self.poll_recv(cx)).await
186 }
187
188 pub fn poll_recv(&self, cx: &mut Context<'_>) -> Poll<Option<T>> {
196 if let Poll::Ready(msg) = self.try_recv() {
197 return Poll::Ready(msg);
198 }
199 LocalWaker::register_in(|| &self.shared.get_ref().blocked_recv, cx.waker());
200
201 self.try_recv()
203 }
204
205 fn try_recv(&self) -> Poll<Option<T>> {
206 let shared = self.shared.get_mut();
207 if let Some(msg) = shared.buffer.pop_front() {
208 Poll::Ready(Some(msg))
209 } else if !shared.has_receiver || self.shared.strong_count() == 1 {
210 Poll::Ready(None)
213 } else {
214 Poll::Pending
215 }
216 }
217}
218
219impl<T> Unpin for Receiver<T> {}
220
221impl<T> Stream for Receiver<T> {
222 type Item = T;
223
224 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
225 self.poll_recv(cx)
226 }
227}
228
229impl<T> FusedStream for Receiver<T> {
230 fn is_terminated(&self) -> bool {
233 self.is_closed() && self.shared.get_ref().buffer.is_empty()
234 }
235}
236
237impl<T> UnwindSafe for Receiver<T> {}
238
239impl<T> Drop for Receiver<T> {
240 fn drop(&mut self) {
241 let (buffer, waker) = {
242 let shared = self.shared.get_mut();
243 shared.has_receiver = false;
244 (
245 std::mem::take(&mut shared.buffer),
246 shared.closed.take_local(),
247 )
248 };
249 wake(waker);
250
251 drop(buffer);
253 }
254}
255
256pub struct SendError<T>(T);
259
260impl<T> std::error::Error for SendError<T> {}
261
262impl<T> fmt::Debug for SendError<T> {
263 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
264 fmt.debug_tuple("SendError").field(&"...").finish()
265 }
266}
267
268impl<T> fmt::Display for SendError<T> {
269 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
270 write!(fmt, "send failed because receiver is gone")
271 }
272}
273
274impl<T> SendError<T> {
275 pub fn into_inner(self) -> T {
277 self.0
278 }
279}
280
281#[cfg(test)]
282mod tests {
283 use super::*;
284 use crate::task::hooks::{ON_CLONE, hook_waker};
285 use crate::{future::lazy, future::stream_recv};
286
287 #[ntex::test]
293 async fn test_mpsc() {
294 let (tx, mut rx) = channel();
295 assert!(format!("{tx:?}").contains("Sender"));
296 assert!(format!("{rx:?}").contains("Receiver"));
297
298 tx.send("test").unwrap();
299 assert_eq!(stream_recv(&mut rx).await.unwrap(), "test");
300
301 let tx2 = tx.clone();
302 tx2.send("test2").unwrap();
303 assert_eq!(stream_recv(&mut rx).await.unwrap(), "test2");
304
305 assert_eq!(
306 lazy(|cx| Pin::new(&mut rx).poll_next(cx)).await,
307 Poll::Pending
308 );
309 drop(tx2);
310 assert_eq!(
311 lazy(|cx| Pin::new(&mut rx).poll_next(cx)).await,
312 Poll::Pending
313 );
314 drop(tx);
315
316 let (tx, mut rx) = channel::<String>();
317 tx.close();
318 assert_eq!(stream_recv(&mut rx).await, None);
319
320 let (tx, rx) = channel();
321 tx.send("test").unwrap();
322 drop(rx);
323 assert!(tx.send("test").is_err());
324
325 let (tx, _) = channel();
326 let tx2 = tx.clone();
327 tx.close();
328 assert!(tx.send("test").is_err());
329 assert!(tx2.send("test").is_err());
330
331 let err = SendError("test");
332 assert!(format!("{err:?}").contains("SendError"));
333 assert!(format!("{err}").contains("send failed because receiver is gone"));
334 assert_eq!(err.into_inner(), "test");
335 }
336
337 #[ntex::test]
345 async fn test_close() {
346 let (tx, rx) = channel::<()>();
347 assert!(!tx.is_closed());
348 assert!(!rx.is_closed());
349 assert!(!rx.is_terminated());
350
351 tx.close();
352 assert!(tx.is_closed());
353 assert!(rx.is_closed());
354 assert!(rx.is_terminated());
355
356 let (tx, rx) = channel::<()>();
357 assert_eq!(lazy(|cx| rx.poll_recv(cx)).await, Poll::Pending);
358 assert!(rx.shared.get_ref().blocked_recv.is_set());
359 rx.close();
360 assert!(tx.is_closed());
361 assert!(!rx.shared.get_ref().blocked_recv.is_set());
362 assert_eq!(lazy(|cx| rx.poll_recv(cx)).await, Poll::Ready(None));
363
364 let (tx, rx) = channel::<()>();
365 drop(tx);
366 assert!(rx.is_closed());
367 assert!(rx.is_terminated());
368 let tx = rx.sender();
369 assert!(tx.is_closed());
370 assert!(rx.is_closed());
371 assert!(rx.is_terminated());
372 assert!(tx.send(()).is_err());
373 assert_eq!(rx.recv().await, None);
374 }
375
376 #[ntex::test]
382 async fn test_poll_closed() {
383 let (tx, rx) = channel::<()>();
384 assert_eq!(lazy(|cx| tx.poll_closed(cx)).await, Poll::Pending);
385 assert!(tx.shared.get_ref().closed.is_set());
386 drop(rx);
387 assert!(!tx.shared.get_ref().closed.is_set());
388 assert_eq!(lazy(|cx| tx.poll_closed(cx)).await, Poll::Ready(()));
389 tx.closed().await;
390
391 let (tx, rx) = channel::<()>();
392 assert_eq!(lazy(|cx| tx.poll_closed(cx)).await, Poll::Pending);
393 rx.close();
394 assert!(!tx.shared.get_ref().closed.is_set());
395 tx.closed().await;
396
397 let (tx, _rx) = channel::<()>();
398 let tx2 = tx.clone();
399 assert_eq!(lazy(|cx| tx2.poll_closed(cx)).await, Poll::Pending);
400 tx.close();
401 assert!(!tx.shared.get_ref().closed.is_set());
402 tx2.closed().await;
403 }
404
405 #[test]
416 fn single_waiter_wakes_latest_task_only() {
417 use crate::task::hooks::counted_waker;
418
419 let (tx, rx) = channel::<u32>();
420 let (first, first_waker) = counted_waker();
421 let (second, second_waker) = counted_waker();
422 let mut first_cx = Context::from_waker(&first_waker);
423 let mut second_cx = Context::from_waker(&second_waker);
424
425 assert_eq!(rx.poll_recv(&mut first_cx), Poll::Pending);
426 assert_eq!(rx.poll_recv(&mut second_cx), Poll::Pending);
427 tx.send(1).unwrap();
428 tx.send(2).unwrap();
429 assert_eq!((first.get(), second.get()), (0, 1));
430 assert_eq!(rx.poll_recv(&mut first_cx), Poll::Ready(Some(1)));
431
432 let tx2 = tx.clone();
433 let (first, first_waker) = counted_waker();
434 let (second, second_waker) = counted_waker();
435 let mut first_cx = Context::from_waker(&first_waker);
436 let mut second_cx = Context::from_waker(&second_waker);
437
438 assert_eq!(tx.poll_closed(&mut first_cx), Poll::Pending);
439 assert_eq!(tx2.poll_closed(&mut second_cx), Poll::Pending);
440 drop(rx);
441 assert_eq!((first.get(), second.get()), (0, 1));
442 assert_eq!(tx.poll_closed(&mut first_cx), Poll::Ready(()));
443 assert_eq!(tx2.poll_closed(&mut second_cx), Poll::Ready(()));
444 }
445
446 #[test]
452 fn test_drop_receiver_reentrant_send() {
453 use std::rc::Rc;
454
455 struct Msg(Option<Sender<Msg>>, Rc<std::cell::Cell<usize>>);
456
457 impl Drop for Msg {
458 fn drop(&mut self) {
459 self.1.set(self.1.get() + 1);
460 if let Some(tx) = self.0.take() {
461 assert!(tx.send(Msg(None, self.1.clone())).is_err());
462 }
463 }
464 }
465
466 let drops = Rc::new(std::cell::Cell::new(0));
467 let (tx, rx) = channel();
468 for _ in 0..4 {
469 tx.send(Msg(Some(tx.clone()), drops.clone())).unwrap();
470 }
471 drop(rx);
472 assert_eq!(drops.get(), 8);
473 assert!(tx.is_closed());
474 }
475
476 #[ntex::test]
482 async fn test_fused_drains_buffer() {
483 let (tx, mut rx) = channel();
484 tx.send(1).unwrap();
485 tx.send(2).unwrap();
486 drop(tx);
487
488 assert!(!rx.is_terminated());
489 assert_eq!(stream_recv(&mut rx).await, Some(1));
490 assert_eq!(stream_recv(&mut rx).await, Some(2));
491 assert!(rx.is_terminated());
492 assert_eq!(stream_recv(&mut rx).await, None);
493
494 let (tx, mut rx) = channel();
495 tx.send(1).unwrap();
496 rx.close();
497 assert!(!rx.is_terminated());
498 assert_eq!(stream_recv(&mut rx).await, Some(1));
499 assert!(rx.is_terminated());
500 }
501
502 #[ntex::test]
507 async fn test_mpsc_recv() {
508 let (tx, rx) = channel();
509 tx.send(1).unwrap();
510 assert_eq!(rx.recv().await, Some(1));
511 drop(tx);
512 assert_eq!(rx.recv().await, None);
513 }
514
515 #[test]
521 fn miri_poll_recv_with_reentrant_clone() {
522 let (tx, rx) = channel();
523 let tx2 = tx.clone();
524 ON_CLONE.set(Some(Box::new(move || tx2.send(1).unwrap())));
525
526 let waker = hook_waker();
527 let mut cx = Context::from_waker(&waker);
528 assert_eq!(rx.poll_recv(&mut cx), Poll::Ready(Some(1)));
529 drop(tx);
530 }
531}