use std::mem; use std::sync::Arc; use std::task::{RawWaker, RawWakerVTable, Waker}; pub trait ArcWake: Sized { /// Create a waker from this self-wakening object fn waker(self: &Arc) -> Waker { unsafe fn rc_vtable() -> &'static RawWakerVTable { &RawWakerVTable::new( |data| { let arc = mem::ManuallyDrop::new(Arc::::from_raw(data.cast::())); let _rc_clone: mem::ManuallyDrop<_> = arc.clone(); RawWaker::new(data, rc_vtable::()) }, |data| Arc::from_raw(data.cast::()).wake(), |data| { let arc = mem::ManuallyDrop::new(Arc::::from_raw(data.cast::())); ArcWake::wake_by_ref(&arc); }, |data| drop(Arc::::from_raw(data.cast::())), ) } unsafe { Waker::from_raw(RawWaker::new( Arc::into_raw(self.clone()).cast(), rc_vtable::(), )) } } fn wake_by_ref(arc_self: &Arc); fn wake(self: Arc) { Self::wake_by_ref(&self) } }