mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-07 00:00:09 +02:00
time: improve the readability of alternative timer (#7801)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::util::linked_list;
|
||||
|
||||
type EntryList = linked_list::LinkedList<CancellationQueueEntry, Entry>;
|
||||
|
||||
#[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<Item = EntryHandle> {
|
||||
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<Item = EntryHandle> {
|
||||
struct Iter(Inner);
|
||||
|
||||
impl Iterator for Iter {
|
||||
type Item = EntryHandle;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
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<Item = EntryHandle> {
|
||||
self.inner.lock().iter()
|
||||
std::mem::take(&mut *self.inner.lock()).into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Expiration> {
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user