2016-08-03 09:55:47 -07:00
|
|
|
use std::io;
|
|
|
|
|
use std::time::{Duration, Instant};
|
|
|
|
|
|
2016-08-17 09:29:05 -07:00
|
|
|
use futures::{Future, Poll};
|
2016-08-03 09:55:47 -07:00
|
|
|
|
|
|
|
|
use LoopHandle;
|
2016-08-26 14:30:46 -07:00
|
|
|
use io::IoFuture;
|
2016-08-03 09:55:47 -07:00
|
|
|
use event_loop::TimeoutToken;
|
|
|
|
|
|
|
|
|
|
/// 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,
|
|
|
|
|
handle: LoopHandle,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl LoopHandle {
|
|
|
|
|
/// 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-08-12 11:54:19 -07:00
|
|
|
pub fn timeout(self, dur: Duration) -> IoFuture<Timeout> {
|
2016-08-03 09:55:47 -07:00
|
|
|
self.timeout_at(Instant::now() + dur)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 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-08-12 11:54:19 -07:00
|
|
|
pub fn timeout_at(self, at: Instant) -> IoFuture<Timeout> {
|
2016-08-03 09:55:47 -07:00
|
|
|
self.add_timeout(at).map(move |token| {
|
|
|
|
|
Timeout {
|
|
|
|
|
token: token,
|
|
|
|
|
handle: self,
|
|
|
|
|
}
|
|
|
|
|
}).boxed()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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-08-03 09:55:47 -07:00
|
|
|
Poll::Ok(())
|
|
|
|
|
} else {
|
2016-08-17 09:29:05 -07:00
|
|
|
self.handle.update_timeout(&self.token);
|
2016-08-03 09:55:47 -07:00
|
|
|
Poll::NotReady
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for Timeout {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
self.handle.cancel_timeout(&self.token);
|
|
|
|
|
}
|
|
|
|
|
}
|