Files
tokio/tokio-timer/src/timer/registration.rs
T
2018-05-08 11:44:17 -07:00

83 lines
2.0 KiB
Rust

use Error;
use timer::{Handle, Entry};
use futures::Poll;
use std::sync::Arc;
use std::time::Instant;
/// Registration with a timer.
///
/// The association between a `Delay` instance and a timer is done lazily in
/// `poll`
#[derive(Debug)]
pub(crate) struct Registration {
entry: Arc<Entry>,
}
impl Registration {
pub fn new(deadline: Instant) -> Registration {
fn is_send<T: Send + Sync>() {}
is_send::<Registration>();
match Handle::try_current() {
Ok(handle) => Registration::new_with_handle(deadline, handle),
Err(_) => Registration::new_error(),
}
}
pub fn new_with_handle(deadline: Instant, handle: Handle) -> Registration {
let inner = match handle.inner() {
Some(inner) => inner,
None => return Registration::new_error(),
};
// Increment the number of active timeouts
if inner.increment().is_err() {
return Registration::new_error();
}
let when = inner.normalize_deadline(deadline);
if when <= inner.elapsed() {
// The deadline has already elapsed, there is no point creating the
// structures.
return Registration {
entry: Arc::new(Entry::new_elapsed(handle)),
};
}
let entry = Arc::new(Entry::new(when, handle));
if inner.queue(&entry).is_err() {
// The timer has shutdown, transition the entry to the error state.
entry.error();
}
Registration { entry }
}
pub fn reset(&self, deadline: Instant) {
Entry::reset(&self.entry, deadline);
}
fn new_error() -> Registration {
let entry = Arc::new(Entry::new_error());
Registration { entry }
}
pub fn is_elapsed(&self) -> bool {
self.entry.is_elapsed()
}
pub fn poll_elapsed(&self) -> Poll<(), Error> {
self.entry.poll_elapsed()
}
}
impl Drop for Registration {
fn drop(&mut self) {
Entry::cancel(&self.entry);
}
}