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