handle same next expiry value

This commit is contained in:
Nikolay Kim 2021-09-04 09:22:03 +06:00
parent 9511caf1db
commit db8a56c62f
2 changed files with 26 additions and 19 deletions

View file

@ -386,10 +386,9 @@ impl Timer {
self.now(inner) + time::Duration::from_millis(millis)
}
fn execute_expired_timers(&mut self, instant: time::Instant) {
fn execute_expired_timers(&mut self) {
let mut clk = self.next_expiry;
self.elapsed = self.next_expiry;
self.elapsed_instant = instant;
for lvl in 0..LVL_DEPTH {
let idx = (clk & LVL_MASK) + lvl * LVL_SIZE;
@ -571,20 +570,28 @@ impl Future for TimerDriver {
drop(inner);
let result = Pin::as_mut(&mut self.sleep).poll(cx).is_ready();
if result {
let instant = self.sleep.deadline();
let now = self.sleep.deadline();
let mut inner = self.inner.borrow_mut();
inner.execute_expired_timers(instant);
inner.elapsed_instant = now;
inner.execute_expired_timers();
if let Some(next_expiry) = inner.next_pending_bucket() {
inner.next_expiry = next_expiry;
inner.flags.insert(Flags::TIMER_ACTIVE);
let exp = inner.next_expiry(&self.inner);
drop(inner);
Pin::as_mut(&mut self.sleep).reset(exp);
return self.poll(cx);
} else {
inner.next_expiry = u64::MAX;
inner.flags.remove(Flags::TIMER_ACTIVE);
loop {
if let Some(next_expiry) = inner.next_pending_bucket() {
if inner.next_expiry == next_expiry {
inner.elapsed += 1;
continue;
}
inner.next_expiry = next_expiry;
inner.flags.insert(Flags::TIMER_ACTIVE);
let exp = inner.next_expiry(&self.inner);
drop(inner);
Pin::as_mut(&mut self.sleep).reset(exp);
return self.poll(cx);
} else {
inner.next_expiry = u64::MAX;
inner.flags.remove(Flags::TIMER_ACTIVE);
}
break;
}
}
}

View file

@ -2,7 +2,7 @@ use std::task::{Context, Poll};
use std::time::{self, Duration, Instant};
use std::{cell::RefCell, convert::Infallible, rc::Rc};
use crate::rt::time::sleep;
use crate::rt::time_driver::sleep_until;
use crate::service::{Service, ServiceFactory};
use crate::util::Ready;
@ -79,7 +79,7 @@ impl LowResTimeService {
};
crate::rt::spawn(async move {
sleep(interval).await;
sleep_until(Instant::now() + interval).await;
inner.borrow_mut().current.take();
});
now
@ -146,7 +146,7 @@ impl SystemTimeService {
};
crate::rt::spawn(async move {
sleep(interval).await;
sleep_until(Instant::now() + interval).await;
inner.borrow_mut().current.take();
});
now
@ -205,7 +205,7 @@ mod tests {
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap();
sleep(wait_time).await;
sleep_until(Instant::now() + wait_time).await;
let second_time = time_service
.now()
@ -227,7 +227,7 @@ mod tests {
let first_time = time_service.now();
sleep(wait_time).await;
sleep_until(Instant::now() + wait_time).await;
let second_time = time_service.now();
assert!(second_time - first_time >= wait_time);