waker.rs 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. use std::mem;
  2. use std::sync::Arc;
  3. use std::task::{RawWaker, RawWakerVTable, Waker};
  4. pub trait ArcWake: Sized {
  5. /// Create a waker from this self-wakening object
  6. fn waker(self: &Arc<Self>) -> Waker {
  7. unsafe fn rc_vtable<T: ArcWake>() -> &'static RawWakerVTable {
  8. &RawWakerVTable::new(
  9. |data| {
  10. let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data.cast::<T>()));
  11. let _rc_clone: mem::ManuallyDrop<_> = arc.clone();
  12. RawWaker::new(data, rc_vtable::<T>())
  13. },
  14. |data| Arc::from_raw(data.cast::<T>()).wake(),
  15. |data| {
  16. let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data.cast::<T>()));
  17. ArcWake::wake_by_ref(&arc);
  18. },
  19. |data| drop(Arc::<T>::from_raw(data.cast::<T>())),
  20. )
  21. }
  22. unsafe {
  23. Waker::from_raw(RawWaker::new(
  24. Arc::into_raw(self.clone()).cast(),
  25. rc_vtable::<Self>(),
  26. ))
  27. }
  28. }
  29. fn wake_by_ref(arc_self: &Arc<Self>);
  30. fn wake(self: Arc<Self>) {
  31. Self::wake_by_ref(&self)
  32. }
  33. }