Skip to content

Commit

Permalink
time: advance frozen time in park_timeout (#2059)
Browse files Browse the repository at this point in the history
This patch improves the behavior of frozen time (a testing utility made
available with the `test-util` feature flag). Instead of of requiring
`time::advance` to be called in order to advance the value returned by
`Instant::now`, calls to `time::Driver::park_timeout` will use the
provided duration to advance the time.

This is the desired behavior as the timeout is used to indicate when the
next scheduled delay needs to be fired.
  • Loading branch information
carllerche authored Jan 6, 2020
1 parent 84ff73e commit f000600
Show file tree
Hide file tree
Showing 10 changed files with 849 additions and 694 deletions.
12 changes: 0 additions & 12 deletions tokio/src/runtime/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,6 @@ impl ThreadContext {
})
}

#[cfg(all(feature = "test-util", feature = "time", test))]
pub(crate) fn with_time_handle(mut self, handle: crate::runtime::time::Handle) -> Self {
self.time_handle = handle;
self
}

#[cfg(all(feature = "test-util", feature = "time", test))]
pub(crate) fn with_clock(mut self, clock: crate::runtime::time::Clock) -> Self {
self.clock.replace(clock);
self
}

#[cfg(all(feature = "io-driver", not(loom)))]
pub(crate) fn io_handle() -> crate::runtime::io::Handle {
CONTEXT.with(|ctx| match *ctx.borrow() {
Expand Down
14 changes: 13 additions & 1 deletion tokio/src/time/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! configurable.
cfg_not_test_util! {
use crate::time::Instant;
use crate::time::{Duration, Instant};

#[derive(Debug, Clone)]
pub(crate) struct Clock {}
Expand All @@ -22,6 +22,14 @@ cfg_not_test_util! {
pub(crate) fn now(&self) -> Instant {
now()
}

pub(crate) fn is_frozen(&self) -> bool {
false
}

pub(crate) fn advance(&self, _dur: Duration) {
unreachable!();
}
}
}

Expand Down Expand Up @@ -137,6 +145,10 @@ cfg_test_util! {
}
}

pub(crate) fn is_frozen(&self) -> bool {
self.inner.frozen.lock().unwrap().is_some()
}

pub(crate) fn advance(&self, duration: Duration) {
let mut frozen = self.inner.frozen.lock().unwrap();

Expand Down
4 changes: 2 additions & 2 deletions tokio/src/time/driver/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ const ERROR: u64 = u64::MAX;
// ===== impl Entry =====

impl Entry {
pub(crate) fn new(deadline: Instant, duration: Duration) -> Arc<Entry> {
let inner = Handle::current().inner().unwrap();
pub(crate) fn new(handle: &Handle, deadline: Instant, duration: Duration) -> Arc<Entry> {
let inner = handle.inner().unwrap();
let entry: Entry;

// Increment the number of active timeouts
Expand Down
20 changes: 17 additions & 3 deletions tokio/src/time/driver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod atomic_stack;
use self::atomic_stack::AtomicStack;

mod entry;
use self::entry::Entry;
pub(super) use self::entry::Entry;

mod handle;
pub(crate) use self::handle::Handle;
Expand Down Expand Up @@ -245,7 +245,14 @@ where
let deadline = self.expiration_instant(when);

if deadline > now {
self.park.park_timeout(deadline - now)?;
let dur = deadline - now;

if self.clock.is_frozen() {
self.park.park_timeout(Duration::from_secs(0))?;
self.clock.advance(dur);
} else {
self.park.park_timeout(dur)?;
}
} else {
self.park.park_timeout(Duration::from_secs(0))?;
}
Expand All @@ -269,7 +276,14 @@ where
let deadline = self.expiration_instant(when);

if deadline > now {
self.park.park_timeout(cmp::min(deadline - now, duration))?;
let duration = cmp::min(deadline - now, duration);

if self.clock.is_frozen() {
self.park.park_timeout(Duration::from_secs(0))?;
self.clock.advance(duration);
} else {
self.park.park_timeout(duration)?;
}
} else {
self.park.park_timeout(Duration::from_secs(0))?;
}
Expand Down
6 changes: 4 additions & 2 deletions tokio/src/time/driver/registration.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::time::driver::Entry;
use crate::time::driver::{Entry, Handle};
use crate::time::{Duration, Error, Instant};

use std::sync::Arc;
Expand All @@ -15,8 +15,10 @@ pub(crate) struct Registration {

impl Registration {
pub(crate) fn new(deadline: Instant, duration: Duration) -> Registration {
let handle = Handle::current();

Registration {
entry: Entry::new(deadline, duration),
entry: Entry::new(&handle, deadline, duration),
}
}

Expand Down
2 changes: 0 additions & 2 deletions tokio/src/time/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
mod mock_clock;
mod test_delay;
mod test_queue;

use crate::time::{self, Instant};
use std::time::Duration;
Expand Down
Loading

0 comments on commit f000600

Please sign in to comment.