diff --git a/tokio/src/runtime/scheduler/util/time_alt.rs b/tokio/src/runtime/scheduler/util/time_alt.rs index e6ea35843..e9d65c88d 100644 --- a/tokio/src/runtime/scheduler/util/time_alt.rs +++ b/tokio/src/runtime/scheduler/util/time_alt.rs @@ -139,11 +139,9 @@ pub(crate) fn shutdown_local_timers( let mut wake_queue = WakeQueue::new(); // simply wake all unregistered timers - for hdl in inject { - if !hdl.is_cancelled() { - unsafe { - wake_queue.push_front(hdl); - } + for hdl in inject.into_iter().filter(|hdl| !hdl.is_cancelled()) { + unsafe { + wake_queue.push_front(hdl); } } diff --git a/tokio/src/runtime/time_alt/cancellation_queue.rs b/tokio/src/runtime/time_alt/cancellation_queue.rs index cfbd1ad2f..167078e3d 100644 --- a/tokio/src/runtime/time_alt/cancellation_queue.rs +++ b/tokio/src/runtime/time_alt/cancellation_queue.rs @@ -4,7 +4,7 @@ use crate::util::linked_list; type EntryList = linked_list::LinkedList; -#[derive(Debug)] +#[derive(Debug, Default)] struct Inner { list: EntryList, } @@ -12,7 +12,9 @@ struct Inner { impl Drop for Inner { fn drop(&mut self) { // consume all entries - let _ = self.iter().count(); + while let Some(hdl) = self.list.pop_front() { + drop(hdl) + } } } @@ -32,30 +34,18 @@ impl Inner { self.list.push_front(hdl); } - fn iter(&mut self) -> impl Iterator { - struct Iter { - list: EntryList, - } - - impl Drop for Iter { - fn drop(&mut self) { - while let Some(hdl) = self.list.pop_front() { - drop(hdl); - } - } - } + fn into_iter(self) -> impl Iterator { + struct Iter(Inner); impl Iterator for Iter { type Item = EntryHandle; fn next(&mut self) -> Option { - self.list.pop_front() + self.0.list.pop_front() } } - Iter { - list: std::mem::take(&mut self.list), - } + Iter(self) } } @@ -84,7 +74,7 @@ pub(crate) struct Receiver { impl Receiver { pub(crate) fn recv_all(&mut self) -> impl Iterator { - self.inner.lock().iter() + std::mem::take(&mut *self.inner.lock()).into_iter() } } diff --git a/tokio/src/runtime/time_alt/wheel/mod.rs b/tokio/src/runtime/time_alt/wheel/mod.rs index e7699457b..324704e9c 100644 --- a/tokio/src/runtime/time_alt/wheel/mod.rs +++ b/tokio/src/runtime/time_alt/wheel/mod.rs @@ -107,39 +107,31 @@ impl Wheel { /// Advances the timer up to the instant represented by `now`. pub(crate) fn take_expired(&mut self, now: u64, wake_queue: &mut WakeQueue) { - loop { - match self.next_expiration() { - Some(ref expiration) if expiration.deadline <= now => { - self.process_expiration(expiration, wake_queue); + while let Some(expiration) = self + .next_expiration() + .filter(|expiration| expiration.deadline <= now) + { + self.process_expiration(&expiration, wake_queue); - self.set_elapsed(expiration.deadline); - } - _ => { - // in this case the poll did not indicate an expiration - // _and_ we were not able to find a next expiration in - // the current list of timers. advance to the poll's - // current time and do nothing else. - self.set_elapsed(now); - break; - } - } + self.set_elapsed(expiration.deadline); } + self.set_elapsed(now); } /// Returns the instant at which the next timeout expires. fn next_expiration(&self) -> Option { // Check all levels - for (level_num, level) in self.levels.iter().enumerate() { - if let Some(expiration) = level.next_expiration(self.elapsed) { + self.levels + .iter() + .enumerate() + .find_map(|(level_num, level)| { + let expiration = level.next_expiration(self.elapsed)?; // There cannot be any expirations at a higher level that happen // before this one. debug_assert!(self.no_expirations_before(level_num + 1, expiration.deadline)); - return Some(expiration); - } - } - - None + Some(expiration) + }) } /// Returns the tick at which this timer wheel next needs to perform some @@ -150,17 +142,10 @@ impl Wheel { /// Used for debug assertions fn no_expirations_before(&self, start_level: usize, before: u64) -> bool { - let mut res = true; - - for level in &self.levels[start_level..] { - if let Some(e2) = level.next_expiration(self.elapsed) { - if e2.deadline < before { - res = false; - } - } - } - - res + self.levels[start_level..] + .iter() + .flat_map(|level| level.next_expiration(self.elapsed)) + .all(|e2| before <= e2.deadline) } /// iteratively find entries that are between the wheel's current