1use alloc::sync::Arc;
10use core::fmt::{Debug, Formatter};
11use core::pin::Pin;
12use core::task::{Context, Poll};
13use crossbeam_queue::SegQueue;
14use futures::task::AtomicWaker;
15
16pub struct Sender<T> {
18 inner: Arc<ChannelInner<T>>,
19}
20
21impl<T> Clone for Sender<T> {
22 fn clone(&self) -> Self {
23 Self { inner: Arc::clone(&self.inner) }
24 }
25}
26
27pub struct Receiver<T> {
29 inner: Arc<ChannelInner<T>>,
30}
31
32struct ChannelInner<T> {
33 queue: SegQueue<T>,
34 waker: AtomicWaker,
35}
36
37#[must_use]
39pub fn unbounded<T>() -> (Sender<T>, Receiver<T>) {
40 let inner = ChannelInner {
41 queue: SegQueue::new(),
42 waker: AtomicWaker::new(),
43 };
44 let inner = Arc::new(inner);
45
46 (Sender { inner: Arc::clone(&inner) }, Receiver { inner })
47}
48
49impl<T> Sender<T> {
50 pub fn push(&self, val: T) {
52 self.inner.queue.push(val);
53 self.inner.waker.wake();
54 }
55}
56
57impl<T> Receiver<T> {
58 pub fn push(&self, val: T) {
60 self.inner.queue.push(val);
61 self.inner.waker.wake();
62 }
63
64 pub fn pop(&self) -> impl Future<Output = T> + '_ {
66 struct Waiter<'a, T>(&'a ChannelInner<T>);
67
68 impl<T> Future for Waiter<'_, T> {
69 type Output = T;
70
71 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
72 if let Some(val) = self.0.queue.pop() { return Poll::Ready(val); }
73 self.0.waker.register(cx.waker());
74 self.0.queue.pop()
75 .map_or(Poll::Pending, Poll::Ready)
76 }
77 }
78
79 Waiter(&self.inner)
80 }
81
82 #[must_use]
84 pub fn try_pop(&self) -> Option<T> {
85 self.inner.queue.pop()
86 }
87
88 #[must_use]
90 pub fn sender(&self) -> Sender<T> {
91 Sender {
92 inner: Arc::clone(&self.inner)
93 }
94 }
95
96 #[must_use]
98 pub fn len(&self) -> usize { self.inner.queue.len() }
99
100 #[must_use]
102 pub fn is_empty(&self) -> bool { self.inner.queue.is_empty() }
103}
104
105impl<T> Debug for Sender<T> {
106 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
107 write!(f, "Sender {{ .. }}")
108 }
109}
110
111impl<T> Debug for Receiver<T> {
112 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
113 write!(f, "Receiver {{ .. }}")
114 }
115}