use mio::Poll as MioPoll;
use mio::{Events, Interest, Token};
use std::collections::HashMap;
use std::io;
use std::task::{Context, Poll as TaskPoll, Waker};
use std::time::Duration;
pub struct Reactor {
poll: MioPoll,
events: Events,
wakers: HashMap<Token, Waker>,
next_token: usize,
}
impl Reactor {
pub fn new() -> io::Result<Self> {
Ok(Self {
poll: MioPoll::new()?,
events: Events::with_capacity(1024),
wakers: HashMap::new(),
next_token: 0,
})
}
pub fn register(
&mut self,
source: &mut impl mio::event::Source,
interest: Interest,
waker: Waker,
) -> Token {
let token = Token(self.next_token);
self.next_token += 1;
self.poll
.registry()
.register(source, token, interest)
.unwrap();
self.wakers.insert(token, waker);
token
}
pub fn poll(&mut self, _cx: &mut Context, timeout: Option<Duration>) -> TaskPoll<()> {
self.poll.poll(&mut self.events, timeout).unwrap();
for event in &self.events {
if let Some(waker) = self.wakers.get(&event.token()) {
waker.wake_by_ref();
}
}
if self.events.is_empty() {
TaskPoll::Pending
} else {
TaskPoll::Ready(())
}
}
}