From 83784fd983bf4347284ec80077d897c22a9f7a50 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 8 Sep 2016 07:46:47 -0700 Subject: [PATCH] Don't remove timeouts that have fired Closes #22 --- src/reactor/mod.rs | 7 ++++--- tests/timeout.rs | 12 ++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/reactor/mod.rs b/src/reactor/mod.rs index 8065a5640..b913748f1 100644 --- a/src/reactor/mod.rs +++ b/src/reactor/mod.rs @@ -69,7 +69,7 @@ struct Inner { // state of the timeout itself. The `TimeoutToken` type is an index into the // `timeouts` slab. timer_heap: Heap<(Instant, usize)>, - timeouts: Slab<(Slot, TimeoutState)>, + timeouts: Slab<(Option, TimeoutState)>, } /// Handle to an event loop, used to construct I/O objects, send messages, and @@ -359,6 +359,7 @@ impl Core { let (_, slab_idx) = inner.timer_heap.pop().unwrap(); trace!("firing timeout: {}", slab_idx); + inner.timeouts[slab_idx].0.take().unwrap(); let handle = inner.timeouts[slab_idx].1.fire(); drop(inner); if let Some(handle) = handle { @@ -457,7 +458,7 @@ impl Inner { } let entry = self.timeouts.vacant_entry().unwrap(); let slot = self.timer_heap.push((at, entry.index())); - let entry = entry.insert((slot, TimeoutState::NotFired)); + let entry = entry.insert((Some(slot), TimeoutState::NotFired)); debug!("added a timeout: {}", entry.index()); Ok((entry.index(), at)) } @@ -470,7 +471,7 @@ impl Inner { fn cancel_timeout(&mut self, token: usize) { debug!("cancel a timeout: {}", token); let pair = self.timeouts.remove(token); - if let Some((slot, _state)) = pair { + if let Some((Some(slot), _state)) = pair { self.timer_heap.remove(slot); } } diff --git a/tests/timeout.rs b/tests/timeout.rs index 3f241cd34..91edb58d2 100644 --- a/tests/timeout.rs +++ b/tests/timeout.rs @@ -23,3 +23,15 @@ fn smoke() { t!(l.run(timeout)); assert!(start.elapsed() >= dur); } + +#[test] +fn two() { + drop(env_logger::init()); + + let mut l = t!(Core::new()); + let dur = Duration::from_millis(10); + let timeout = t!(Timeout::new(dur, &l.handle())); + t!(l.run(timeout)); + let timeout = t!(Timeout::new(dur, &l.handle())); + t!(l.run(timeout)); +}