mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-19 00:00:09 +02:00
timer: finish updating timer (#1222)
* timer: restructure feature flags * update timer tests * Add `async-traits` to CI This also disables a buggy `threadpool` test. This test should be fixed in the future. Refs #1225
This commit is contained in:
@@ -4,7 +4,6 @@ use std::cell::Cell;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
use tokio_executor::Enter;
|
||||
|
||||
/// A handle to a source of time.
|
||||
///
|
||||
@@ -108,9 +107,9 @@ impl fmt::Debug for Clock {
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there already is a default clock set.
|
||||
pub fn with_default<F, R>(clock: &Clock, enter: &mut Enter, f: F) -> R
|
||||
pub fn with_default<F, R>(clock: &Clock, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Enter) -> R,
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
CLOCK.with(|cell| {
|
||||
assert!(
|
||||
@@ -132,6 +131,6 @@ where
|
||||
|
||||
cell.set(Some(clock as *const Clock));
|
||||
|
||||
f(enter)
|
||||
f()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ impl Delay {
|
||||
}
|
||||
|
||||
// Used by `Timeout<Stream>`
|
||||
#[cfg(feature = "timeout-stream")]
|
||||
#[cfg(feature = "async-traits")]
|
||||
pub(crate) fn reset_timeout(&mut self) {
|
||||
self.registration.reset_timeout();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::clock::now;
|
||||
use crate::timer::Handle;
|
||||
use crate::wheel::{self, Wheel};
|
||||
use crate::{Delay, Error};
|
||||
use futures_core::Stream;
|
||||
|
||||
use slab::Slab;
|
||||
use std::cmp;
|
||||
use std::future::Future;
|
||||
@@ -347,6 +347,34 @@ impl<T> DelayQueue<T> {
|
||||
Key::new(key)
|
||||
}
|
||||
|
||||
/// TODO: Dox... also is the fn signature correct?
|
||||
pub fn poll_next(
|
||||
&mut self,
|
||||
cx: &mut task::Context<'_>,
|
||||
) -> Poll<Option<Result<Expired<T>, Error>>> {
|
||||
let item = ready!(self.poll_idx(cx));
|
||||
Poll::Ready(item.map(|result| {
|
||||
result.map(|idx| {
|
||||
let data = self.slab.remove(idx);
|
||||
debug_assert!(data.next.is_none());
|
||||
debug_assert!(data.prev.is_none());
|
||||
|
||||
Expired {
|
||||
key: Key::new(idx),
|
||||
data: data.inner,
|
||||
deadline: self.start + Duration::from_millis(data.when),
|
||||
}
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
/// TODO: Dox... also is the fn signature correct?
|
||||
pub async fn next(&mut self) -> Option<Result<Expired<T>, Error>> {
|
||||
use async_util::future::poll_fn;
|
||||
|
||||
poll_fn(|cx| self.poll_next(cx)).await
|
||||
}
|
||||
|
||||
/// Insert `value` into the queue set to expire after the requested duration
|
||||
/// elapses.
|
||||
///
|
||||
@@ -696,26 +724,14 @@ impl<T> DelayQueue<T> {
|
||||
// We never put `T` in a `Pin`...
|
||||
impl<T> Unpin for DelayQueue<T> {}
|
||||
|
||||
impl<T> Stream for DelayQueue<T> {
|
||||
#[cfg(feature = "async-traits")]
|
||||
impl<T> futures_core::Stream for DelayQueue<T> {
|
||||
// DelayQueue seems much more specific, where a user may care that it
|
||||
// has reached capacity, so return those errors instead of panicking.
|
||||
type Item = Result<Expired<T>, Error>;
|
||||
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
let item = ready!(self.poll_idx(cx));
|
||||
Poll::Ready(item.map(|result| {
|
||||
result.map(|idx| {
|
||||
let data = self.slab.remove(idx);
|
||||
debug_assert!(data.next.is_none());
|
||||
debug_assert!(data.prev.is_none());
|
||||
|
||||
Expired {
|
||||
key: Key::new(idx),
|
||||
data: data.inner,
|
||||
deadline: self.start + Duration::from_millis(data.when),
|
||||
}
|
||||
})
|
||||
}))
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
DelayQueue::poll_next(self.get_mut(), cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::clock;
|
||||
use crate::Delay;
|
||||
use futures_core::Stream;
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::task::{self, Poll};
|
||||
@@ -52,12 +52,9 @@ impl Interval {
|
||||
pub(crate) fn new_with_delay(delay: Delay, duration: Duration) -> Interval {
|
||||
Interval { delay, duration }
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for Interval {
|
||||
type Item = Instant;
|
||||
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
/// TODO: dox
|
||||
pub fn poll_next(&mut self, cx: &mut task::Context<'_>) -> Poll<Option<Instant>> {
|
||||
// Wait for the delay to be done
|
||||
ready!(Pin::new(&mut self.delay).poll(cx));
|
||||
|
||||
@@ -72,4 +69,20 @@ impl Stream for Interval {
|
||||
// Return the current instant
|
||||
Poll::Ready(Some(now))
|
||||
}
|
||||
|
||||
/// TODO: dox
|
||||
pub async fn next(&mut self) -> Option<Instant> {
|
||||
use async_util::future::poll_fn;
|
||||
|
||||
poll_fn(|cx| self.poll_next(cx)).await
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "async-traits")]
|
||||
impl futures_core::Stream for Interval {
|
||||
type Item = Instant;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
Interval::poll_next(self.get_mut(), cx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))]
|
||||
#![feature(async_await)]
|
||||
|
||||
//! Utilities for tracking time.
|
||||
//!
|
||||
@@ -41,9 +42,8 @@ macro_rules! ready {
|
||||
}
|
||||
|
||||
pub mod clock;
|
||||
#[cfg(feature = "delay-queue")]
|
||||
pub mod delay_queue;
|
||||
#[cfg(feature = "throttle")]
|
||||
#[cfg(feature = "async-traits")]
|
||||
pub mod throttle;
|
||||
pub mod timeout;
|
||||
pub mod timer;
|
||||
@@ -51,16 +51,13 @@ pub mod timer;
|
||||
mod atomic;
|
||||
mod delay;
|
||||
mod error;
|
||||
#[cfg(feature = "interval")]
|
||||
mod interval;
|
||||
mod wheel;
|
||||
|
||||
pub use delay::Delay;
|
||||
#[cfg(feature = "delay-queue")]
|
||||
#[doc(inline)]
|
||||
pub use delay_queue::DelayQueue;
|
||||
pub use error::Error;
|
||||
#[cfg(feature = "interval")]
|
||||
pub use interval::Interval;
|
||||
#[doc(inline)]
|
||||
pub use timeout::Timeout;
|
||||
|
||||
@@ -25,7 +25,7 @@ impl<T> Throttle<T> {
|
||||
pub fn new(stream: T, duration: Duration) -> Self {
|
||||
Self {
|
||||
delay: Delay::new_timeout(clock::now() + duration, duration),
|
||||
has_delayed: false,
|
||||
has_delayed: true,
|
||||
stream: stream,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
use crate::clock::now;
|
||||
use crate::Delay;
|
||||
#[cfg(feature = "timeout-stream")]
|
||||
use futures_core::Stream;
|
||||
use std::fmt;
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
@@ -175,10 +173,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "timeout-stream")]
|
||||
impl<T> Stream for Timeout<T>
|
||||
#[cfg(feature = "async-traits")]
|
||||
impl<T> futures_core::Stream for Timeout<T>
|
||||
where
|
||||
T: Stream,
|
||||
T: futures_core::Stream,
|
||||
{
|
||||
type Item = Result<T::Item, Elapsed>;
|
||||
|
||||
@@ -202,8 +200,10 @@ where
|
||||
}
|
||||
|
||||
// Now check the timer
|
||||
ready!(self.map_unchecked_mut(|me| &mut me.delay).poll(cx));
|
||||
ready!(self.as_mut().map_unchecked_mut(|me| &mut me.delay).poll(cx));
|
||||
|
||||
// if delay was ready, timeout elapsed!
|
||||
self.as_mut().get_unchecked_mut().delay.reset_timeout();
|
||||
Poll::Ready(Some(Err(Elapsed(()))))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::Instant;
|
||||
use tokio_executor::Enter;
|
||||
|
||||
/// Handle to timer instance.
|
||||
///
|
||||
@@ -58,9 +57,9 @@ thread_local! {
|
||||
///
|
||||
/// [`Delay`]: ../struct.Delay.html
|
||||
/// [`Delay::new`]: ../struct.Delay.html#method.new
|
||||
pub fn with_default<F, R>(handle: &Handle, enter: &mut Enter, f: F) -> R
|
||||
pub fn with_default<F, R>(handle: &Handle, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Enter) -> R,
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
// Ensure that the timer is removed from the thread-local context
|
||||
// when leaving the scope. This handles cases that involve panicking.
|
||||
@@ -96,7 +95,7 @@ where
|
||||
*current = Some(handle.clone());
|
||||
}
|
||||
|
||||
f(enter)
|
||||
f()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ impl Registration {
|
||||
}
|
||||
|
||||
// Used by `Timeout<Stream>`
|
||||
#[cfg(feature = "timeout-stream")]
|
||||
#[cfg(feature = "async-traits")]
|
||||
pub fn reset_timeout(&mut self) {
|
||||
let deadline = crate::clock::now() + self.entry.time_ref().duration;
|
||||
self.entry.time_mut().deadline = deadline;
|
||||
|
||||
Reference in New Issue
Block a user