1 #![unstable(feature = "wake_trait", issue = "69912")]
2 //! Types and Traits for working with asynchronous tasks.
3 use core
::mem
::{self, 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`][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.
20 /// [arc]: ../../std/sync/struct.Arc.html
21 #[unstable(feature = "wake_trait", issue = "69912")]
24 #[unstable(feature = "wake_trait", issue = "69912")]
25 fn wake(self: Arc
<Self>);
27 /// Wake this task without consuming the waker.
29 /// If an executor supports a cheaper way to wake without consuming the
30 /// waker, it should override this method. By default, it clones the
31 /// [`Arc`] and calls `wake` on the clone.
32 #[unstable(feature = "wake_trait", issue = "69912")]
33 fn wake_by_ref(self: &Arc
<Self>) {
38 #[unstable(feature = "wake_trait", issue = "69912")]
39 impl<W
: Wake
+ Send
+ Sync
+ '
static> From
<Arc
<W
>> for Waker
{
40 fn from(waker
: Arc
<W
>) -> Waker
{
41 // SAFETY: This is safe because raw_waker safely constructs
42 // a RawWaker from Arc<W>.
43 unsafe { Waker::from_raw(raw_waker(waker)) }
47 #[unstable(feature = "wake_trait", issue = "69912")]
48 impl<W
: Wake
+ Send
+ Sync
+ '
static> From
<Arc
<W
>> for RawWaker
{
49 fn from(waker
: Arc
<W
>) -> RawWaker
{
54 // NB: This private function for constructing a RawWaker is used, rather than
55 // inlining this into the `From<Arc<W>> for RawWaker` impl, to ensure that
56 // the safety of `From<Arc<W>> for Waker` does not depend on the correct
57 // trait dispatch - instead both impls call this function directly and
60 fn raw_waker
<W
: Wake
+ Send
+ Sync
+ '
static>(waker
: Arc
<W
>) -> RawWaker
{
61 // Increment the reference count of the arc to clone it.
62 unsafe fn clone_waker
<W
: Wake
+ Send
+ Sync
+ '
static>(waker
: *const ()) -> RawWaker
{
63 let waker
: Arc
<W
> = Arc
::from_raw(waker
as *const W
);
64 mem
::forget(Arc
::clone(&waker
));
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
: Arc
<W
> = 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
: ManuallyDrop
<Arc
<W
>> = 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 mem
::drop(Arc
::from_raw(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
>),