diff options
Diffstat (limited to 'tokio-executor/src/park.rs')
-rw-r--r-- | tokio-executor/src/park.rs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/tokio-executor/src/park.rs b/tokio-executor/src/park.rs index b7c4dbf0..35cd846b 100644 --- a/tokio-executor/src/park.rs +++ b/tokio-executor/src/park.rs @@ -46,8 +46,10 @@ use crossbeam_utils::sync::{Parker, Unparker}; use std::marker::PhantomData; +use std::mem; use std::rc::Rc; use std::sync::Arc; +use std::task::{RawWaker, RawWakerVTable, Waker}; use std::time::Duration; /// Block the current thread. @@ -223,3 +225,44 @@ impl Unpark for UnparkThread { self.inner.unpark(); } } + +static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake_by_ref, drop); + +impl UnparkThread { + pub(crate) fn into_waker(self) -> Waker { + unsafe { + let raw = unparker_to_raw_waker(self.inner); + Waker::from_raw(raw) + } + } +} + +unsafe fn unparker_to_raw_waker(unparker: Unparker) -> RawWaker { + RawWaker::new(Unparker::into_raw(unparker), &VTABLE) +} + +unsafe fn clone(raw: *const ()) -> RawWaker { + let unparker = Unparker::from_raw(raw); + + // Increment the ref count + mem::forget(unparker.clone()); + + unparker_to_raw_waker(unparker) +} + +unsafe fn wake(raw: *const ()) { + let unparker = Unparker::from_raw(raw); + unparker.unpark(); +} + +unsafe fn wake_by_ref(raw: *const ()) { + let unparker = Unparker::from_raw(raw); + unparker.unpark(); + + // We don't actually own a reference to the unparker + mem::forget(unparker); +} + +unsafe fn drop(raw: *const ()) { + let _ = Unparker::from_raw(raw); +} |