third_party/rust/tokio-timer/src/timer/registration.rs
author Bastien Orivel <eijebong@bananium.fr>
Wed, 22 Aug 2018 20:19:04 +0200
changeset 488156 03df1a267ea54f1024d3f015f4bf781477262c92
child 539572 4d31fcd3085d87085a42fafeea827d41a17890d6
permissions -rw-r--r--
Bug 1484462 - Revendor Rust dependencies. r=ato

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);
    }
}