Files
tokio/src/reactor/timeout.rs
T

91 lines
2.7 KiB
Rust
Raw Normal View History

2016-09-02 11:07:52 -07:00
//! Support for creating futures that represent timeouts.
//!
//! This module contains the `Timeout` type which is a future that will resolve
//! at a particular point in the future.
2016-08-03 09:55:47 -07:00
use std::io;
use std::time::{Duration, Instant};
2016-09-01 16:42:48 -07:00
use futures::{Future, Poll, Async};
2016-08-03 09:55:47 -07:00
2016-09-02 11:07:52 -07:00
use reactor::Handle;
use reactor::timeout_token::TimeoutToken;
2016-08-26 14:30:46 -07:00
use io::IoFuture;
2016-08-03 09:55:47 -07:00
/// A future representing the notification that a timeout has occurred.
///
/// Timeouts are created through the `LoopHandle::timeout` or
/// `LoopHandle::timeout_at` methods indicating when a timeout should fire at.
/// Note that timeouts are not intended for high resolution timers, but rather
/// they will likely fire some granularity after the exact instant that they're
/// otherwise indicated to fire at.
pub struct Timeout {
token: TimeoutToken,
2016-09-02 11:07:52 -07:00
handle: Handle,
}
/// Future returned from `Timeout::new` and `Timeout::new_at` which will resolve
/// to the actual `Timeout` itself.
pub struct TimeoutNew {
inner: IoFuture<Timeout>,
2016-08-03 09:55:47 -07:00
}
2016-09-02 11:07:52 -07:00
impl Timeout {
2016-08-03 09:55:47 -07:00
/// Creates a new timeout which will fire at `dur` time into the future.
///
/// This function will return a future that will resolve to the actual
/// timeout object. The timeout object itself is then a future which will be
/// set to fire at the specified point in the future.
2016-09-02 11:07:52 -07:00
pub fn new(dur: Duration, handle: &Handle) -> TimeoutNew {
Timeout::new_at(Instant::now() + dur, handle)
2016-08-03 09:55:47 -07:00
}
/// Creates a new timeout which will fire at the time specified by `at`.
///
/// This function will return a future that will resolve to the actual
/// timeout object. The timeout object itself is then a future which will be
/// set to fire at the specified point in the future.
2016-09-02 11:07:52 -07:00
pub fn new_at(at: Instant, handle: &Handle) -> TimeoutNew {
let handle = handle.clone();
TimeoutNew {
inner: TimeoutToken::new(at, &handle).map(move |token| {
Timeout {
token: token,
handle: handle,
}
}).boxed(),
}
2016-08-03 09:55:47 -07:00
}
}
impl Future for Timeout {
type Item = ();
type Error = io::Error;
2016-08-17 09:29:05 -07:00
fn poll(&mut self) -> Poll<(), io::Error> {
2016-08-03 09:55:47 -07:00
// TODO: is this fast enough?
2016-08-17 18:14:32 -07:00
let now = Instant::now();
if *self.token.when() <= now {
2016-09-01 16:42:48 -07:00
Ok(Async::Ready(()))
2016-08-03 09:55:47 -07:00
} else {
2016-09-02 11:07:52 -07:00
self.token.update_timeout(&self.handle);
2016-09-01 16:42:48 -07:00
Ok(Async::NotReady)
2016-08-03 09:55:47 -07:00
}
}
}
2016-09-02 11:07:52 -07:00
impl Future for TimeoutNew {
type Item = Timeout;
type Error = io::Error;
fn poll(&mut self) -> Poll<Timeout, io::Error> {
self.inner.poll()
}
}
2016-08-03 09:55:47 -07:00
impl Drop for Timeout {
fn drop(&mut self) {
2016-09-02 11:07:52 -07:00
self.token.cancel_timeout(&self.handle);
2016-08-03 09:55:47 -07:00
}
}