diff options
Diffstat (limited to 'src/eventloop.rs')
-rw-r--r-- | src/eventloop.rs | 85 |
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); + } } } } |