diff options
-rw-r--r-- | tokio/src/time/driver/entry.rs | 56 | ||||
-rw-r--r-- | tokio/src/time/driver/handle.rs | 43 | ||||
-rw-r--r-- | tokio/src/time/driver/mod.rs | 2 |
3 files changed, 38 insertions, 63 deletions
diff --git a/tokio/src/time/driver/entry.rs b/tokio/src/time/driver/entry.rs index 708b6cfb..d5fab897 100644 --- a/tokio/src/time/driver/entry.rs +++ b/tokio/src/time/driver/entry.rs @@ -1,6 +1,6 @@ use crate::loom::sync::atomic::AtomicU64; use crate::sync::AtomicWaker; -use crate::time::driver::{HandlePriv, Inner}; +use crate::time::driver::{Handle, Inner}; use crate::time::{Duration, Error, Instant}; use std::cell::UnsafeCell; @@ -105,36 +105,24 @@ const ERROR: u64 = u64::MAX; impl Entry { pub(crate) fn new(deadline: Instant, duration: Duration) -> Arc<Entry> { - let handle_priv = HandlePriv::current(); - let handle = handle_priv.inner().unwrap(); + let inner = Handle::current().inner().unwrap(); + let entry: Entry; // Increment the number of active timeouts - if handle.increment().is_err() { - // TODO(kleimkuhler): Transition to error state instead of - // panicking? - panic!("failed to add entry; timer at capacity"); - }; - - let when = handle.normalize_deadline(deadline); - let state = if when <= handle.elapsed() { - ELAPSED + if inner.increment().is_err() { + entry = Entry::new2(deadline, duration, Weak::new(), ERROR) } else { - when - }; - - let entry = Arc::new(Entry { - time: CachePadded(UnsafeCell::new(Time { deadline, duration })), - 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()), - }); + let when = inner.normalize_deadline(deadline); + let state = if when <= inner.elapsed() { + ELAPSED + } else { + when + }; + entry = Entry::new2(deadline, duration, Arc::downgrade(&inner), state); + } - if handle.queue(&entry).is_err() { + let entry = Arc::new(entry); + if inner.queue(&entry).is_err() { 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>> { self.inner.upgrade() } diff --git a/tokio/src/time/driver/handle.rs b/tokio/src/time/driver/handle.rs index 86ff904e..7d21ad0d 100644 --- a/tokio/src/time/driver/handle.rs +++ b/tokio/src/time/driver/handle.rs @@ -5,26 +5,20 @@ use std::marker::PhantomData; use std::sync::{Arc, Weak}; /// Handle to time driver instance. -#[derive(Debug, Clone)] -pub(crate) struct Handle { - inner: Option<HandlePriv>, -} - -/// Like `Handle` but never `None`. #[derive(Clone)] -pub(crate) struct HandlePriv { +pub(crate) struct Handle { inner: Weak<Inner>, } thread_local! { /// 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)] /// Guard that unsets the current default timer on drop. pub(crate) struct DefaultGuard<'a> { - prev: Option<HandlePriv>, + prev: Option<Handle>, _lifetime: PhantomData<&'a u8>, } @@ -47,10 +41,6 @@ pub(crate) fn set_default(handle: &Handle) -> DefaultGuard<'_> { let mut current = current.borrow_mut(); let prev = current.take(); - let handle = handle - .as_priv() - .unwrap_or_else(|| panic!("`handle` does not reference a timer")); - *current = Some(handle.clone()); DefaultGuard { @@ -61,23 +51,11 @@ pub(crate) fn set_default(handle: &Handle) -> DefaultGuard<'_> { } impl Handle { - pub(crate) fn new(inner: Weak<Inner>) -> Handle { - let inner = HandlePriv { inner }; - Handle { inner: Some(inner) } + /// Create a new timer `Handle` from a shared `Inner` timer state. + pub(crate) fn new(inner: Weak<Inner>) -> Self { + 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. /// /// # Panics @@ -94,15 +72,10 @@ impl HandlePriv { pub(crate) fn inner(&self) -> Option<Arc<Inner>> { 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 { - write!(f, "HandlePriv") + write!(f, "Handle") } } diff --git a/tokio/src/time/driver/mod.rs b/tokio/src/time/driver/mod.rs index e3b45101..4a1ba4fe 100644 --- a/tokio/src/time/driver/mod.rs +++ b/tokio/src/time/driver/mod.rs @@ -7,7 +7,7 @@ mod entry; use self::entry::Entry; mod handle; -pub(crate) use self::handle::{set_default, Handle, HandlePriv}; +pub(crate) use self::handle::{set_default, Handle}; mod registration; pub(crate) use self::registration::Registration; |