Skip to content

Commit

Permalink
feat: allow downcasting pinned Sleep
Browse files Browse the repository at this point in the history
This commit allows downcasting pinned `Sleep` object to support
implementations of `Timer::reset`.

One example where this is useful is when using `TokioSleep`, i.e.
`Sleep` provided by tokio.
  • Loading branch information
dswij committed Mar 22, 2023
1 parent 2219a06 commit 806a943
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 7 deletions.
13 changes: 8 additions & 5 deletions benches/support/tokiort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ impl Timer for TokioTimer {
}

fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
if sleep.downcast_ref::<TokioSleep>().is_some() {
*sleep = self.sleep_until(new_deadline);
if let Some(sleep) = sleep.as_mut().downcast_mut_pin::<TokioSleep>() {
sleep.reset(new_deadline.into())
}
}
}
Expand Down Expand Up @@ -81,7 +81,10 @@ impl Future for TokioSleep {
}
}

// Use HasSleep to get tokio::time::Sleep to implement Unpin.
// see https://docs.rs/tokio/latest/tokio/time/struct.Sleep.html

impl Sleep for TokioSleep {}

impl TokioSleep {
pub fn reset(self: Pin<&mut Self>, deadline: Instant) {
self.project().inner.as_mut().reset(deadline.into());
}
}
27 changes: 25 additions & 2 deletions src/rt/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
//! }
//!
//! fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
//! if sleep.downcast_ref::<TokioSleep>().is_some() {
//! *sleep = self.sleep_until(new_deadline);
//! if let Some(sleep) = sleep.as_mut().downcast_mut_pin::<TokioSleep>() {
//! sleep.reset(new_deadline.into())
//! }
//! }
//! }
Expand All @@ -51,6 +51,12 @@
//! }
//!
//! impl Sleep for TokioSleep {}
//!
//! impl TokioSleep {
//! pub fn reset(self: Pin<&mut Self>, deadline: Instant) {
//! self.project().inner.as_mut().reset(deadline.into());
//! }
//! }
//! ````
use std::{
Expand Down Expand Up @@ -120,6 +126,23 @@ impl dyn Sleep {
None
}
}

/// Downcast a pinned &mut Sleep object to its original type
pub fn downcast_mut_pin<T>(self: Pin<&mut Self>) -> Option<Pin<&'static mut T>>
where
T: Sleep + 'static,
{
if self.is::<T>() {
unsafe {
let inner = Pin::into_inner_unchecked(self);
Some(Pin::new_unchecked(
&mut *(&mut *inner as *mut dyn Sleep as *mut T),
))
}
} else {
None
}
}
}

mod private {
Expand Down

0 comments on commit 806a943

Please sign in to comment.