use std::{sync::{mpsc, Arc, Mutex}, io};
use mio::{Waker, event, Token};
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
let (tx, rx) = mpsc::channel();
let waker = Arc::new(Mutex::new(None));
(Sender { waker: waker.clone(), tx }, Receiver { waker, rx })
}
pub struct Receiver<T> {
waker: Arc<Mutex<Option<Waker>>>,
rx: mpsc::Receiver<T>
}
impl<T> Receiver<T> {
pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
self.rx.try_recv()
}
}
impl<T> event::Source for Receiver<T> {
fn register(
&mut self,
registry: &mio::Registry,
token: Token,
_: mio::Interest,
) -> io::Result<()> {
let mut waker = self.waker.lock().unwrap();
if waker.is_none() {
*waker = Some(Waker::new(registry, token)?);
}
Ok(())
}
fn reregister(
&mut self,
registry: &mio::Registry,
token: Token,
_: mio::Interest,
) -> io::Result<()> {
let mut waker = self.waker.lock().unwrap();
*waker = Some(Waker::new(registry, token)?);
Ok(())
}
fn deregister(&mut self, _: &mio::Registry) -> io::Result<()> {
let mut waker = self.waker.lock().unwrap();
*waker = None;
Ok(())
}
}
pub struct Sender<T> {
waker: Arc<Mutex<Option<Waker>>>,
tx: mpsc::Sender<T>
}
impl<T> Sender<T> {
pub fn send(&self, t: T) -> Result<(), mpsc::SendError<T>> {
self.tx.send(t)?;
if let Some(waker) = &mut *self.waker.lock().unwrap() {
let _ = waker.wake();
}
Ok(())
}
}
impl<T> Clone for Sender<T> {
fn clone(&self) -> Self {
Self { waker: self.waker.clone(), tx: self.tx.clone() }
}
}