use std::future::Future;
use std::sync::{Arc, Mutex};
use std::task::{Poll, Waker};
pub fn new<T>() -> (Sender<T>, Receiver<T>) {
let inner = Arc::new(Mutex::new(Inner {
item: None,
waker: None,
}));
let sender = Sender {
inner: inner.clone(),
};
let receiver = Receiver { inner };
(sender, receiver)
}
pub struct Sender<T> {
inner: Arc<Mutex<Inner<T>>>,
}
impl<T> Sender<T> {
pub fn send(self, item: T) {
let mut inner = self.inner.lock().unwrap();
inner.item = Some(item);
if let Some(waker) = inner.waker.take() {
waker.wake();
}
}
}
pub struct Receiver<T> {
inner: Arc<Mutex<Inner<T>>>,
}
impl<T: Send + 'static> Receiver<T> {
pub fn recv(self) -> impl Future<Output = T> {
std::future::poll_fn(move |context| {
let mut inner = self.inner.lock().unwrap();
match inner.item.take() {
Some(item) => Poll::Ready(item),
None => {
inner.waker = Some(context.waker().clone());
Poll::Pending
}
}
})
}
}
struct Inner<T> {
item: Option<T>,
waker: Option<Waker>,
}