Struct tokio::runtime::time::Driver

source ·
pub(crate) struct Driver {
    park: IoStack,
}
Expand description

Time implementation that drives Sleep, Interval, and Timeout.

A Driver instance tracks the state necessary for managing time and notifying the Sleep instances once their deadlines are reached.

It is expected that a single instance manages many individual Sleep instances. The Driver implementation is thread-safe and, as such, is able to handle callers from across threads.

After creating the Driver instance, the caller must repeatedly call park or park_timeout. The time driver will perform no work unless park or park_timeout is called repeatedly.

The driver has a resolution of one millisecond. Any unit of time that falls between milliseconds are rounded up to the next millisecond.

When an instance is dropped, any outstanding Sleep instance that has not elapsed will be notified with an error. At this point, calling poll on the Sleep instance will result in panic.

§Implementation

The time driver is based on the paper by Varghese and Lauck.

A hashed timing wheel is a vector of slots, where each slot handles a time slice. As time progresses, the timer walks over the slot for the current instant, and processes each entry for that slot. When the timer reaches the end of the wheel, it starts again at the beginning.

The implementation maintains six wheels arranged in a set of levels. As the levels go up, the slots of the associated wheel represent larger intervals of time. At each level, the wheel has 64 slots. Each slot covers a range of time equal to the wheel at the lower level. At level zero, each slot represents one millisecond of time.

The wheels are:

  • Level 0: 64 x 1 millisecond slots.
  • Level 1: 64 x 64 millisecond slots.
  • Level 2: 64 x ~4 second slots.
  • Level 3: 64 x ~4 minute slots.
  • Level 4: 64 x ~4 hour slots.
  • Level 5: 64 x ~12 day slots.

When the timer processes entries at level zero, it will notify all the Sleep instances as their deadlines have been reached. For all higher levels, all entries will be redistributed across the wheel at the next level down. Eventually, as time progresses, entries with Sleep instances will either be canceled (dropped) or their associated entries will reach level zero and be notified.

Fields§

§park: IoStack

Parker to delegate to.

Implementations§

source§

impl Driver

source

pub(crate) fn new(park: IoStack, clock: &Clock, shards: u32) -> (Driver, Handle)

Creates a new Driver instance that uses park to block the current thread and time_source to get the current time and convert to ticks.

Specifying the source of time is useful when testing.

source

pub(crate) fn park(&mut self, handle: &Handle)

source

pub(crate) fn park_timeout(&mut self, handle: &Handle, duration: Duration)

source

pub(crate) fn shutdown(&mut self, rt_handle: &Handle)

source

fn park_internal(&mut self, rt_handle: &Handle, limit: Option<Duration>)

source

fn park_thread_timeout(&mut self, rt_handle: &Handle, duration: Duration)

Trait Implementations§

source§

impl Debug for Driver

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Driver

§

impl RefUnwindSafe for Driver

§

impl Send for Driver

§

impl Sync for Driver

§

impl Unpin for Driver

§

impl UnwindSafe for Driver

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.