embedded_executor/
wake.rs

1use core::task::{
2    RawWaker,
3    Waker,
4};
5
6#[cfg(any(feature = "alloc", feature = "std"))]
7use alloc::sync::Arc;
8
9/// Wake trait
10///
11/// Should be combined with [`crate::Sleep`] in order to be used with the
12/// [`crate::AllocExecutor`].
13pub trait Wake {
14    /// Wake up the sleepers.
15    fn wake(&self);
16}
17
18#[cfg(any(feature = "alloc", feature = "std"))]
19pub(crate) trait WakeExt: Wake + Sized {
20    fn into_raw_waker(self: Arc<Self>) -> RawWaker {
21        RawWaker::new(Arc::into_raw(self) as _, arc::arc_waker_vtable::<Self>())
22    }
23
24    fn into_waker(self: Arc<Self>) -> Waker {
25        unsafe { Waker::from_raw(self.into_raw_waker()) }
26    }
27}
28
29#[cfg(any(feature = "alloc", feature = "std"))]
30impl<T> WakeExt for T where T: Sized + Wake {}
31
32#[cfg(any(feature = "alloc", feature = "std"))]
33mod arc {
34    use core::{
35        mem,
36        task::RawWakerVTable,
37    };
38
39    use super::*;
40
41    pub unsafe fn clone_arc_waker_raw<T: Wake>(ptr: *const ()) -> RawWaker {
42        let arc = Arc::<T>::from_raw(ptr as _);
43        let cloned = arc.clone();
44        mem::forget(arc);
45        cloned.into_raw_waker()
46    }
47
48    pub unsafe fn drop_arc_waker_raw<T>(ptr: *const ()) {
49        drop(Arc::<T>::from_raw(ptr as _));
50    }
51
52    pub unsafe fn wake_arc_waker_raw<T: Wake>(ptr: *const ()) {
53        let arc = Arc::<T>::from_raw(ptr as _);
54        arc.wake();
55    }
56
57    pub unsafe fn wake_by_ref_arc_waker_raw<T: Wake>(ptr: *const ()) {
58        let arc = Arc::<T>::from_raw(ptr as _);
59        arc.wake();
60        mem::forget(arc);
61    }
62
63    pub fn arc_waker_vtable<T: Wake>() -> &'static RawWakerVTable {
64        &RawWakerVTable::new(
65            clone_arc_waker_raw::<T>,
66            wake_arc_waker_raw::<T>,
67            wake_by_ref_arc_waker_raw::<T>,
68            drop_arc_waker_raw::<T>,
69        )
70    }
71}