mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-10-01 12:20:39 +00:00
time: Remove HandlePriv
(#1896)
## Motivation #1800 removed the lazy binding of `Delay`s to timers. With the removal of the logic required for that, `HandlePriv` is no longer needed. This PR removes the use of `HandlePriv`. A `TODO` was also removed that would panic if when registering a new `Delay` the current timer handle was full. That has been fixed to now immediately transition that `Delay` to an error state that can be handled in a similar way to other error states. Signed-off-by: Kevin Leimkuhler <kleimkuhler@icloud.com>
This commit is contained in:
parent
0e729aa341
commit
dbcd1f9a09
@ -1,6 +1,6 @@
|
|||||||
use crate::loom::sync::atomic::AtomicU64;
|
use crate::loom::sync::atomic::AtomicU64;
|
||||||
use crate::sync::AtomicWaker;
|
use crate::sync::AtomicWaker;
|
||||||
use crate::time::driver::{HandlePriv, Inner};
|
use crate::time::driver::{Handle, Inner};
|
||||||
use crate::time::{Duration, Error, Instant};
|
use crate::time::{Duration, Error, Instant};
|
||||||
|
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
@ -105,36 +105,24 @@ const ERROR: u64 = u64::MAX;
|
|||||||
|
|
||||||
impl Entry {
|
impl Entry {
|
||||||
pub(crate) fn new(deadline: Instant, duration: Duration) -> Arc<Entry> {
|
pub(crate) fn new(deadline: Instant, duration: Duration) -> Arc<Entry> {
|
||||||
let handle_priv = HandlePriv::current();
|
let inner = Handle::current().inner().unwrap();
|
||||||
let handle = handle_priv.inner().unwrap();
|
let entry: Entry;
|
||||||
|
|
||||||
// Increment the number of active timeouts
|
// Increment the number of active timeouts
|
||||||
if handle.increment().is_err() {
|
if inner.increment().is_err() {
|
||||||
// TODO(kleimkuhler): Transition to error state instead of
|
entry = Entry::new2(deadline, duration, Weak::new(), ERROR)
|
||||||
// panicking?
|
} else {
|
||||||
panic!("failed to add entry; timer at capacity");
|
let when = inner.normalize_deadline(deadline);
|
||||||
};
|
let state = if when <= inner.elapsed() {
|
||||||
|
|
||||||
let when = handle.normalize_deadline(deadline);
|
|
||||||
let state = if when <= handle.elapsed() {
|
|
||||||
ELAPSED
|
ELAPSED
|
||||||
} else {
|
} else {
|
||||||
when
|
when
|
||||||
};
|
};
|
||||||
|
entry = Entry::new2(deadline, duration, Arc::downgrade(&inner), state);
|
||||||
|
}
|
||||||
|
|
||||||
let entry = Arc::new(Entry {
|
let entry = Arc::new(entry);
|
||||||
time: CachePadded(UnsafeCell::new(Time { deadline, duration })),
|
if inner.queue(&entry).is_err() {
|
||||||
inner: handle_priv.into_inner(),
|
|
||||||
waker: AtomicWaker::new(),
|
|
||||||
state: AtomicU64::new(state),
|
|
||||||
queued: AtomicBool::new(false),
|
|
||||||
next_atomic: UnsafeCell::new(ptr::null_mut()),
|
|
||||||
when: UnsafeCell::new(None),
|
|
||||||
next_stack: UnsafeCell::new(None),
|
|
||||||
prev_stack: UnsafeCell::new(ptr::null_mut()),
|
|
||||||
});
|
|
||||||
|
|
||||||
if handle.queue(&entry).is_err() {
|
|
||||||
entry.error();
|
entry.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,6 +302,20 @@ impl Entry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new2(deadline: Instant, duration: Duration, inner: Weak<Inner>, state: u64) -> Self {
|
||||||
|
Self {
|
||||||
|
time: CachePadded(UnsafeCell::new(Time { deadline, duration })),
|
||||||
|
inner,
|
||||||
|
waker: AtomicWaker::new(),
|
||||||
|
state: AtomicU64::new(state),
|
||||||
|
queued: AtomicBool::new(false),
|
||||||
|
next_atomic: UnsafeCell::new(ptr::null_mut()),
|
||||||
|
when: UnsafeCell::new(None),
|
||||||
|
next_stack: UnsafeCell::new(None),
|
||||||
|
prev_stack: UnsafeCell::new(ptr::null_mut()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn upgrade_inner(&self) -> Option<Arc<Inner>> {
|
fn upgrade_inner(&self) -> Option<Arc<Inner>> {
|
||||||
self.inner.upgrade()
|
self.inner.upgrade()
|
||||||
}
|
}
|
||||||
|
@ -5,26 +5,20 @@ use std::marker::PhantomData;
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
/// Handle to time driver instance.
|
/// Handle to time driver instance.
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub(crate) struct Handle {
|
|
||||||
inner: Option<HandlePriv>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Like `Handle` but never `None`.
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct HandlePriv {
|
pub(crate) struct Handle {
|
||||||
inner: Weak<Inner>,
|
inner: Weak<Inner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
/// Tracks the timer for the current execution context.
|
/// Tracks the timer for the current execution context.
|
||||||
static CURRENT_TIMER: RefCell<Option<HandlePriv>> = RefCell::new(None)
|
static CURRENT_TIMER: RefCell<Option<Handle>> = RefCell::new(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// Guard that unsets the current default timer on drop.
|
/// Guard that unsets the current default timer on drop.
|
||||||
pub(crate) struct DefaultGuard<'a> {
|
pub(crate) struct DefaultGuard<'a> {
|
||||||
prev: Option<HandlePriv>,
|
prev: Option<Handle>,
|
||||||
_lifetime: PhantomData<&'a u8>,
|
_lifetime: PhantomData<&'a u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,10 +41,6 @@ pub(crate) fn set_default(handle: &Handle) -> DefaultGuard<'_> {
|
|||||||
let mut current = current.borrow_mut();
|
let mut current = current.borrow_mut();
|
||||||
let prev = current.take();
|
let prev = current.take();
|
||||||
|
|
||||||
let handle = handle
|
|
||||||
.as_priv()
|
|
||||||
.unwrap_or_else(|| panic!("`handle` does not reference a timer"));
|
|
||||||
|
|
||||||
*current = Some(handle.clone());
|
*current = Some(handle.clone());
|
||||||
|
|
||||||
DefaultGuard {
|
DefaultGuard {
|
||||||
@ -61,23 +51,11 @@ pub(crate) fn set_default(handle: &Handle) -> DefaultGuard<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Handle {
|
impl Handle {
|
||||||
pub(crate) fn new(inner: Weak<Inner>) -> Handle {
|
/// Create a new timer `Handle` from a shared `Inner` timer state.
|
||||||
let inner = HandlePriv { inner };
|
pub(crate) fn new(inner: Weak<Inner>) -> Self {
|
||||||
Handle { inner: Some(inner) }
|
Handle { inner }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_priv(&self) -> Option<&HandlePriv> {
|
|
||||||
self.inner.as_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Handle {
|
|
||||||
fn default() -> Handle {
|
|
||||||
Handle { inner: None }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HandlePriv {
|
|
||||||
/// Try to get a handle to the current timer.
|
/// Try to get a handle to the current timer.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
@ -94,15 +72,10 @@ impl HandlePriv {
|
|||||||
pub(crate) fn inner(&self) -> Option<Arc<Inner>> {
|
pub(crate) fn inner(&self) -> Option<Arc<Inner>> {
|
||||||
self.inner.upgrade()
|
self.inner.upgrade()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consume the handle, returning the weak Inner ref.
|
|
||||||
pub(crate) fn into_inner(self) -> Weak<Inner> {
|
|
||||||
self.inner
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for HandlePriv {
|
impl fmt::Debug for Handle {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "HandlePriv")
|
write!(f, "Handle")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ mod entry;
|
|||||||
use self::entry::Entry;
|
use self::entry::Entry;
|
||||||
|
|
||||||
mod handle;
|
mod handle;
|
||||||
pub(crate) use self::handle::{set_default, Handle, HandlePriv};
|
pub(crate) use self::handle::{set_default, Handle};
|
||||||
|
|
||||||
mod registration;
|
mod registration;
|
||||||
pub(crate) use self::registration::Registration;
|
pub(crate) use self::registration::Registration;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user