summaryrefslogtreecommitdiff
path: root/src/eventloop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/eventloop.rs')
-rw-r--r--src/eventloop.rs85
1 files changed, 44 insertions, 41 deletions
diff --git a/src/eventloop.rs b/src/eventloop.rs
index 9192401..48c5984 100644
--- a/src/eventloop.rs
+++ b/src/eventloop.rs
@@ -92,7 +92,7 @@ impl From<TToken> for usize { fn from(val: TToken) -> usize { val.0 } }
pub struct EventLoop {
poll: Poll,
- tokens: Slab<MToken, Token>,
+ regs: Slab<Option<MToken>, Token>,
timer: Timer<TToken>,
timers: Slab<Option<(MToken,Timeout)>, TToken>,
// A machine entry is set to None during a method call on the Machine object.
@@ -106,57 +106,59 @@ pub struct Context<'a> {
impl<'a> Context<'a> {
- // This method is opinionated in always providing a PollOpt::level(). It's the only option that
- // makes sense. :)
- pub fn register<E: ?Sized>(&mut self, io: &E, interest: mio::Ready) -> Token where E: mio::Evented {
- let token = slab_insert(&mut self.parent.tokens, self.machine);
- self.parent.poll.register(io, token, interest, mio::PollOpt::level()).unwrap();
- token
+ pub fn reg_alloc(&mut self) -> Token {
+ slab_insert(&mut self.parent.regs, None)
}
- pub fn reregister<E: ?Sized>(&mut self, io: &E, token: Token, interest: mio::Ready) where E: mio::Evented {
- assert_eq!(self.parent.tokens[token], self.machine);
- self.parent.poll.reregister(io, token, interest, mio::PollOpt::level()).unwrap();
+ pub fn reg_free<E: ?Sized>(&mut self, io: &E, token: Token) where E: mio::Evented {
+ if let Some(Some(_)) = self.parent.regs.remove(token) {
+ self.parent.poll.deregister(io).unwrap();
+ }
}
- pub fn deregister<E: ?Sized>(&mut self, io: &E, token: Token) where E: mio::Evented {
- assert_eq!(self.parent.tokens[token], self.machine);
- self.parent.tokens.remove(token);
- self.parent.poll.deregister(io).unwrap();
+ pub fn reg_set<E: ?Sized>(&mut self, io: &E, token: Token, interest: mio::Ready) where E: mio::Evented {
+ let r = self.parent.regs.entry(token).expect("Invalid token in reg_set").replace(Some(self.machine));
+ match r {
+ None => { self.parent.poll. register(io, token, interest, mio::PollOpt::level()).unwrap(); }
+ Some(_) => { self.parent.poll.reregister(io, token, interest, mio::PollOpt::level()).unwrap(); },
+ }
+ }
+
+ pub fn reg_unset<E: ?Sized>(&mut self, io: &E, token: Token) where E: mio::Evented {
+ let mut r = self.parent.regs.get_mut(token).expect("Invalid token in reg_unset");
+ if let Some(_) = *r {
+ self.parent.poll.deregister(io).unwrap();
+ }
+ *r = None;
}
- // The _timeout() methods behave the same as the above register methods, and follow the same
- // control flow, independent of whether the timeout has passed in between or not:
- // 1. set_timeout() or alloc_timeout() to get and initialize a token,
- // 2. Followed by any number of reset_timeout() to change the duration of the timer if it is
- // still active, or set the new timeout after it has fired.
- // 3. cancel_timeout() to stop the timer if it still active, and deallocate the timeout
- // Allocates a timeout token but does not set a timeout. The token can be activated with
- // reset_timeout()
- pub fn alloc_timeout(&mut self) -> TToken {
+ pub fn timeout_alloc(&mut self) -> TToken {
slab_insert(&mut self.parent.timers, None)
}
- pub fn set_timeout(&mut self, d: Duration) -> TToken {
- let token = self.alloc_timeout();
- self.reset_timeout(token, d);
- token
+ pub fn timeout_free(&mut self, token: TToken) {
+ if let Some(Some((_, ref timeout))) = self.parent.timers.remove(token) {
+ self.parent.timer.cancel_timeout(timeout);
+ }
}
- pub fn reset_timeout(&mut self, token: TToken, d: Duration) {
- if let Some((_, ref timeout)) = self.parent.timers[token] {
+ pub fn timeout_set(&mut self, token: TToken, d: Duration) {
+ let newval = Some((self.machine, self.parent.timer.set_timeout(d, token).unwrap()));
+ let oldval = self.parent.timers.entry(token).expect("Invalid token in timeout_unset").replace(newval);
+ if let Some((_, ref timeout)) = oldval {
self.parent.timer.cancel_timeout(timeout);
}
- self.parent.timers[token] = Some((self.machine, self.parent.timer.set_timeout(d, token).unwrap()));
}
- pub fn cancel_timeout(&mut self, token: TToken) {
- if let Some( Some((_, timeout)) ) = self.parent.timers.remove(token) {
- self.parent.timer.cancel_timeout(&timeout);
+ pub fn timeout_unset(&mut self, token: TToken) {
+ let oldval = self.parent.timers.entry(token).expect("Invalid token in timeout_unset").replace(None);
+ if let Some((_, ref timeout)) = oldval {
+ self.parent.timer.cancel_timeout(timeout);
}
}
+
pub fn spawn<F>(&mut self, f: F) where F: Send + 'static + FnOnce(&mut Context) -> Box<Machine> {
self.parent.spawn(f);
}
@@ -181,7 +183,7 @@ impl EventLoop {
EventLoop {
poll: poll,
- tokens: Slab::with_capacity(16),
+ regs: Slab::with_capacity(16),
timer: timer,
timers: Slab::with_capacity(16),
machines: Slab::with_capacity(16),
@@ -221,7 +223,7 @@ impl EventLoop {
}
fn dispatch_io(&mut self, event: mio::Event) {
- if let Some(&mtoken) = self.tokens.get(event.token()) {
+ if let Some(&Some(mtoken)) = self.regs.get(event.token()) {
self.dispatch(mtoken, |m, ctx| {
trace!("[{}] Calling handle for event {} state {:?}", mtoken.0, event.token().0, event.kind());
m.handle(ctx, event)
@@ -245,12 +247,13 @@ impl EventLoop {
let mut events = Events::with_capacity(64);
debug!("Entering event loop");
loop {
- self.poll.poll(&mut events, None).unwrap();
- for event in events.iter() {
- if event.token() == TIMER_TOKEN {
- self.dispatch_timeout();
- } else {
- self.dispatch_io(event);
+ if let Ok(_) = self.poll.poll(&mut events, None) {
+ for event in events.iter() {
+ if event.token() == TIMER_TOKEN {
+ self.dispatch_timeout();
+ } else {
+ self.dispatch_io(event);
+ }
}
}
}