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
37pub fn unbounded<T>() -> (Sender<T>, Receiver<T>) {
39 let inner = ChannelInner {
40 queue: SegQueue::new(),
41 waker: AtomicWaker::new(),
42 };
43 let inner = Arc::new(inner);
44
45 (Sender { inner: Arc::clone(&inner) }, Receiver { inner })
46}
47
48impl<T> Sender<T> {
49 pub fn push(&self, val: T) {
51 self.inner.queue.push(val);
52 self.inner.waker.wake();
53 }
54}
55
56impl<T> Receiver<T> {
57 pub fn push(&self, val: T) {
59 self.inner.queue.push(val);
60 self.inner.waker.wake();
61 }
62
63 pub fn pop(&self) -> impl Future<Output = T> + '_ {
65 struct Waiter<'a, T>(&'a ChannelInner<T>);
66
67 impl<T> Future for Waiter<'_, T> {
68 type Output = T;
69
70 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
71 if let Some(val) = self.0.queue.pop() { return Poll::Ready(val); }
72 self.0.waker.register(cx.waker());
73 match self.0.queue.pop() {
74 Some(val) => Poll::Ready(val),
75 None => Poll::Pending,
76 }
77 }
78 }
79
80 Waiter(&self.inner)
81 }
82
83 pub fn try_pop(&self) -> Option<T> {
85 self.inner.queue.pop()
86 }
87
88 pub fn sender(&self) -> Sender<T> {
90 Sender {
91 inner: Arc::clone(&self.inner)
92 }
93 }
94
95 pub fn len(&self) -> usize { self.inner.queue.len() }
97}
98
99impl<T> Debug for Sender<T> {
100 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
101 write!(f, "Sender {{ .. }}")
102 }
103}
104
105impl<T> Debug for Receiver<T> {
106 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
107 write!(f, "Receiver {{ .. }}")
108 }
109}