//! [![crates.io version](https://img.shields.io/crates/v/safina-timer.svg)](https://crates.io/crates/safina-timer)
//! [![license: Apache 2.0](https://gitlab.com/leonhard-llc/safina-rs/-/raw/main/license-apache-2.0.svg)](http://www.apache.org/licenses/LICENSE-2.0)
//! [![unsafe forbidden](https://gitlab.com/leonhard-llc/safina-rs/-/raw/main/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/)
//! [![pipeline status](https://gitlab.com/leonhard-llc/safina-rs/badges/main/pipeline.svg)](https://gitlab.com/leonhard-llc/safina-rs/-/pipelines)
//!
//! Provides async [`sleep_for`](https://docs.rs/safina-timer/latest/safina_timer/fn.sleep_for.html)
//! and [`sleep_until`](https://docs.rs/safina-timer/latest/safina_timer/fn.sleep_until.html)
//! functions.
//!
//! This crate is part of [`safina`](https://crates.io/crates/safina),
//! a safe async runtime.
//!
//! # Features
//! - `forbid(unsafe_code)`
//! - Depends only on `std`
//! - 100% test coverage
//! - Source of time is
//! [`std::thread::park_timeout`](https://doc.rust-lang.org/std/thread/fn.park_timeout.html)
//! via
//! [`std::sync::mpsc::Receiver::recv_timeout`](https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html#method.recv_timeout).
//! - Works with [`safina-executor`](https://crates.io/crates/safina-executor)
//! or any async executor
//!
//! # Limitations
//! - Building on `stable` requires the feature `once_cell`.
//! This uses [`once_cell`](https://crates.io/crates/once_cell) crate
//! which contains some unsafe code.
//! This is necessary until
//! [`std::lazy::OnceCell`](https://doc.rust-lang.org/std/lazy/struct.OnceCell.html)
//! is stable.
//! - Timers complete around 2ms late, but never early
//! - Allocates memory
//!
//! # Examples
//! ```rust
//! # use core::time::Duration;
//! # async fn f() {
//! safina_timer::start_timer_thread();
//! let duration = Duration::from_secs(10);
//! safina_timer::sleep_for(duration).await;
//! # }
//! ```
//!
//! ```rust
//! # use core::time::Duration;
//! # use std::time::Instant;
//! # async fn f() {
//! safina_timer::start_timer_thread();
//! let deadline =
//! Instant::now() + Duration::from_secs(1);
//! safina_timer::sleep_until(deadline).await;
//! # }
//! ```
//!
//! ```rust
//! # use core::time::Duration;
//! # use std::time::Instant;
//! # async fn read_request() -> Result<(), std::io::Error> { Ok(()) }
//! # async fn read_data(id: ()) -> Result<(), std::io::Error> { Ok(()) }
//! # fn process_data(data: ()) -> Result<(), std::io::Error> { Ok(()) }
//! # async fn write_data(data: ()) -> Result<(), std::io::Error> { Ok(()) }
//! # async fn send_response(response: ()) -> Result<(), std::io::Error> { Ok(()) }
//! # async fn f() -> Result<(), std::io::Error> {
//! safina_timer::start_timer_thread();
//! let deadline =
//! Instant::now() + Duration::from_secs(1);
//! let req = safina_timer::with_deadline(
//! read_request(), deadline).await??;
//! let data = safina_timer::with_deadline(
//! read_data(req), deadline).await??;
//! safina_timer::with_deadline(
//! write_data(data), deadline ).await??;
//! safina_timer::with_deadline(
//! send_response(data), deadline).await??;
//! # Ok(())
//! # }
//! ```
//!
//! ```rust
//! # use core::time::Duration;
//! # use std::time::Instant;
//! # async fn read_request() -> Result<(), std::io::Error> { Ok(()) }
//! # async fn read_data(id: ()) -> Result<(), std::io::Error> { Ok(()) }
//! # fn process_data(data: ()) -> Result<(), std::io::Error> { Ok(()) }
//! # async fn write_data(data: ()) -> Result<(), std::io::Error> { Ok(()) }
//! # async fn send_response(response: ()) -> Result<(), std::io::Error> { Ok(()) }
//! # async fn f() -> Result<(), std::io::Error> {
//! safina_timer::start_timer_thread();
//! let req = safina_timer::with_timeout(
//! read_request(), Duration::from_secs(1)
//! ).await??;
//! let data = safina_timer::with_timeout(
//! read_data(req), Duration::from_secs(2)
//! ).await??;
//! safina_timer::with_timeout(
//! write_data(data), Duration::from_secs(2)
//! ).await??;
//! safina_timer::with_timeout(
//! send_response(data),
//! Duration::from_secs(1)
//! ).await??;
//! # Ok(())
//! # }
//! ```
//!
//! # Documentation
//! <https://docs.rs/safina-timer>
//!
//! # Alternatives
//! - [futures-timer](https://crates.io/crates/futures-timer)
//! - popular
//! - Supports: Wasm, Linux, Windows, macOS
//! - Contains generous amounts of `unsafe` code
//! - Uses `std::thread::park_timeout` as its source of time
//! - [async-io](https://crates.io/crates/async-io)
//! - popular
//! - single and repeating timers
//! - Supports: Linux, Windows, macOS, iOS, Android, and many others.
//! - Uses [polling](https://crates.io/crates/polling) crate
//! which makes unsafe calls to OS.
//! - [async-timer](https://crates.io/crates/async-timer)
//! - Supports: Linux & Android
//! - Makes unsafe calls to OS
//! - [tokio](https://crates.io/crates/tokio)
//! - very popular
//! - single and repeating timers
//! - Supports: Linux, macOS, other unix-like operating systems, Windows
//! - Fast, internally complicated, and full of `unsafe`
//! - [embedded-async-timer](https://crates.io/crates/embedded-async-timer)
//! - `no_std`
//! - Supports `bare_metal`
//!
//! # Changelog
//! - v0.1.11 - Remove some type constraints.
//! - v0.1.10 - Use `safina-executor` v0.2.0.
//! - v0.1.9 - Name the timer thread.
//! - v0.1.8 - Increase test coverage
//! - v0.1.7 - Support stable with rust 1.51 and `once_cell`.
//! - v0.1.6 - Update dependencies
//! - v0.1.5 - Update docs
//! - v0.1.4 - Upgrade to new safina-executor version which removes need for `Box::pin`.
//! - v0.1.3 - Add badges to readme
//! - v0.1.2
//! - Update [`with_deadline`](https://docs.rs/safina-timer/latest/safina_timer/fn.with_deadline.html)
//! and [`with_timeout`](https://docs.rs/safina-timer/latest/safina_timer/fn.with_timeout.html):
//! - Make them panic on `TimerThreadNotStarted` error and
//! return new [`DeadlineExceeded`](https://docs.rs/safina-timer/latest/safina_timer/struct.DeadlineExceeded.html)
//! struct instead of `DeadlineError` enum.
//! This allows callers to write a match clause like `Err(DeadlineExceeded)`.
//! - Make them use
//! [`std::boxed::Box::pin`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.pin)
//! so callers don't have to.
//! - Make [`sleep_until`](https://docs.rs/safina-timer/latest/safina_timer/fn.sleep_until.html)
//! and [`sleep_for`](https://docs.rs/safina-timer/latest/safina_timer/fn.sleep_for.html)
//! return `()` and
//! panic if [`start_timer_thread()`](fn.start_timer_thread.html) has not been called.
//! - v0.1.1
//! - Use most recent waker passed to `SleepFuture::poll`, as required by the
//! [`std::future::Future::poll`](https://doc.rust-lang.org/stable/std/future/trait.Future.html#tymethod.poll)
//! contract.
//! - Add [`with_deadline`](https://docs.rs/safina-timer/latest/safina_timer/fn.with_deadline.html)
//! and [`with_timeout`](https://docs.rs/safina-timer/latest/safina_timer/fn.with_timeout.html)
//! functions.
//! - v0.1.0 - First published version
//!
//! # TO DO
//! - Add a way to schedule jobs (`FnOnce` structs).
//!
//! # Release Process
//! 1. Edit `Cargo.toml` and bump version number.
//! 1. Run `./release.sh`
pub use *;
pub use *;
use Reverse;
use ;
use Waker;
use BinaryHeap;
use Error;
use ;
use ;
use Instant;
pub
static TIMER_THREAD_SENDER: SyncOnceCell =
new;
static TIMER_THREAD_SENDER: OnceCell =
new;
/// Starts the worker thread, if it's not already started.
/// You must call this before calling [`sleep_until`] or [`sleep_for`].
///
/// The thread is called `"safina_timer"`.
/// Call [`start_timer_thread`] to prevent this error.