1 #![unstable(feature = "wake_trait", issue = "69912")]
2 //! Types and Traits for working with asynchronous tasks.
3 use core::mem::ManuallyDrop;
4 use core::task::{RawWaker, RawWakerVTable, Waker};
8 /// The implementation of waking a task on an executor.
10 /// This trait can be used to create a [`Waker`]. An executor can define an
11 /// implementation of this trait, and use that to construct a Waker to pass
12 /// to the tasks that are executed on that executor.
14 /// This trait is a memory-safe and ergonomic alternative to constructing a
15 /// [`RawWaker`]. It supports the common executor design in which the data used
16 /// to wake up a task is stored in an [`Arc`]. Some executors (especially
17 /// those for embedded systems) cannot use this API, which is why [`RawWaker`]
18 /// exists as an alternative for those systems.
19 #[unstable(feature = "wake_trait", issue = "69912")]
22 #[unstable(feature = "wake_trait", issue = "69912")]
23 fn wake(self: Arc<Self>);
25 /// Wake this task without consuming the waker.
27 /// If an executor supports a cheaper way to wake without consuming the
28 /// waker, it should override this method. By default, it clones the
29 /// [`Arc`] and calls `wake` on the clone.
30 #[unstable(feature = "wake_trait", issue = "69912")]
31 fn wake_by_ref(self: &Arc<Self>) {
36 #[unstable(feature = "wake_trait", issue = "69912")]
37 impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
38 fn from(waker: Arc<W>) -> Waker {
39 // SAFETY: This is safe because raw_waker safely constructs
40 // a RawWaker from Arc<W>.
41 unsafe { Waker::from_raw(raw_waker(waker)) }
45 #[unstable(feature = "wake_trait", issue = "69912")]
46 impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
47 fn from(waker: Arc<W>) -> RawWaker {
52 // NB: This private function for constructing a RawWaker is used, rather than
53 // inlining this into the `From<Arc<W>> for RawWaker` impl, to ensure that
54 // the safety of `From<Arc<W>> for Waker` does not depend on the correct
55 // trait dispatch - instead both impls call this function directly and
58 fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
59 // Increment the reference count of the arc to clone it.
60 unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {
61 unsafe { Arc::incr_strong_count(waker as *const W) };
64 &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
68 // Wake by value, moving the Arc into the Wake::wake function
69 unsafe fn wake<W: Wake + Send + Sync + 'static>(waker: *const ()) {
70 let waker = unsafe { Arc::from_raw(waker as *const W) };
71 <W as Wake>::wake(waker);
74 // Wake by reference, wrap the waker in ManuallyDrop to avoid dropping it
75 unsafe fn wake_by_ref<W: Wake + Send + Sync + 'static>(waker: *const ()) {
76 let waker = unsafe { ManuallyDrop::new(Arc::from_raw(waker as *const W)) };
77 <W as Wake>::wake_by_ref(&waker);
80 // Decrement the reference count of the Arc on drop
81 unsafe fn drop_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) {
82 unsafe { Arc::decr_strong_count(waker as *const W) };
86 Arc::into_raw(waker) as *const (),
87 &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),