33 issue = "50547" ) ]
44
55use fmt;
6- use marker:: Unpin ;
6+ use marker:: { PhantomData , Unpin } ;
77
88/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
99/// which provides customized wakeup behavior.
@@ -36,6 +36,10 @@ impl RawWaker {
3636 /// The `vtable` customizes the behavior of a `Waker` which gets created
3737 /// from a `RawWaker`. For each operation on the `Waker`, the associated
3838 /// function in the `vtable` of the underlying `RawWaker` will be called.
39+ #[ rustc_promotable]
40+ #[ unstable( feature = "futures_api" ,
41+ reason = "futures in libcore are unstable" ,
42+ issue = "50547" ) ]
3943 pub const fn new ( data : * const ( ) , vtable : & ' static RawWakerVTable ) -> RawWaker {
4044 RawWaker {
4145 data,
@@ -63,21 +67,103 @@ pub struct RawWakerVTable {
6367 /// required for this additional instance of a [`RawWaker`] and associated
6468 /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
6569 /// of the same task that would have been awoken by the original [`RawWaker`].
66- pub clone : unsafe fn ( * const ( ) ) -> RawWaker ,
70+ clone : unsafe fn ( * const ( ) ) -> RawWaker ,
6771
6872 /// This function will be called when `wake` is called on the [`Waker`].
6973 /// It must wake up the task associated with this [`RawWaker`].
7074 ///
7175 /// The implemention of this function must not consume the provided data
7276 /// pointer.
73- pub wake : unsafe fn ( * const ( ) ) ,
77+ wake : unsafe fn ( * const ( ) ) ,
78+
79+ /// This function gets called when a [`RawWaker`] gets dropped.
80+ ///
81+ /// The implementation of this function must make sure to release any
82+ /// resources that are associated with this instance of a [`RawWaker`] and
83+ /// associated task.
84+ drop : unsafe fn ( * const ( ) ) ,
85+ }
7486
87+ impl RawWakerVTable {
88+ /// Creates a new `RawWakerVTable` from the provided `clone`, `wake`, and
89+ /// `drop` functions.
90+ ///
91+ /// # `clone`
92+ ///
93+ /// This function will be called when the [`RawWaker`] gets cloned, e.g. when
94+ /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned.
95+ ///
96+ /// The implementation of this function must retain all resources that are
97+ /// required for this additional instance of a [`RawWaker`] and associated
98+ /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
99+ /// of the same task that would have been awoken by the original [`RawWaker`].
100+ ///
101+ /// # `wake`
102+ ///
103+ /// This function will be called when `wake` is called on the [`Waker`].
104+ /// It must wake up the task associated with this [`RawWaker`].
105+ ///
106+ /// The implemention of this function must not consume the provided data
107+ /// pointer.
108+ ///
109+ /// # `drop`
110+ ///
75111 /// This function gets called when a [`RawWaker`] gets dropped.
76112 ///
77113 /// The implementation of this function must make sure to release any
78114 /// resources that are associated with this instance of a [`RawWaker`] and
79115 /// associated task.
80- pub drop : unsafe fn ( * const ( ) ) ,
116+ #[ rustc_promotable]
117+ #[ unstable( feature = "futures_api" ,
118+ reason = "futures in libcore are unstable" ,
119+ issue = "50547" ) ]
120+ pub const fn new (
121+ clone : unsafe fn ( * const ( ) ) -> RawWaker ,
122+ wake : unsafe fn ( * const ( ) ) ,
123+ drop : unsafe fn ( * const ( ) ) ,
124+ ) -> Self {
125+ Self {
126+ clone,
127+ wake,
128+ drop,
129+ }
130+ }
131+ }
132+
133+ /// The `Context` of an asynchronous task.
134+ ///
135+ /// Currently, `Context` only serves to provide access to a `&Waker`
136+ /// which can be used to wake the current task.
137+ pub struct Context < ' a > {
138+ waker : & ' a Waker ,
139+ // Ensure we future-proof against variance changes by including
140+ // an `&mut` reference with the provided lifetime.
141+ _marker : PhantomData < & ' a mut ( ) > ,
142+ }
143+
144+ impl < ' a > Context < ' a > {
145+ /// Create a new `Context` from a `&Waker`.
146+ #[ inline]
147+ pub fn from_waker ( waker : & ' a Waker ) -> Self {
148+ Context {
149+ waker,
150+ _marker : PhantomData ,
151+ }
152+ }
153+
154+ /// Returns a reference to the `Waker` for the current task.
155+ #[ inline]
156+ pub fn waker ( & self ) -> & ' a Waker {
157+ & self . waker
158+ }
159+ }
160+
161+ impl fmt:: Debug for Context < ' _ > {
162+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
163+ f. debug_struct ( "Context" )
164+ . field ( "waker" , & self . waker )
165+ . finish ( )
166+ }
81167}
82168
83169/// A `Waker` is a handle for waking up a task by notifying its executor that it
@@ -98,6 +184,7 @@ unsafe impl Sync for Waker {}
98184
99185impl Waker {
100186 /// Wake up the task associated with this `Waker`.
187+ #[ inline]
101188 pub fn wake ( & self ) {
102189 // The actual wakeup call is delegated through a virtual function call
103190 // to the implementation which is defined by the executor.
@@ -115,6 +202,7 @@ impl Waker {
115202 /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
116203 ///
117204 /// This function is primarily used for optimization purposes.
205+ #[ inline]
118206 pub fn will_wake ( & self , other : & Waker ) -> bool {
119207 self . waker == other. waker
120208 }
@@ -124,6 +212,7 @@ impl Waker {
124212 /// The behavior of the returned `Waker` is undefined if the contract defined
125213 /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
126214 /// Therefore this method is unsafe.
215+ #[ inline]
127216 pub unsafe fn new_unchecked ( waker : RawWaker ) -> Waker {
128217 Waker {
129218 waker,
@@ -132,6 +221,7 @@ impl Waker {
132221}
133222
134223impl Clone for Waker {
224+ #[ inline]
135225 fn clone ( & self ) -> Self {
136226 Waker {
137227 // SAFETY: This is safe because `Waker::new_unchecked` is the only way
@@ -143,6 +233,7 @@ impl Clone for Waker {
143233}
144234
145235impl Drop for Waker {
236+ #[ inline]
146237 fn drop ( & mut self ) {
147238 // SAFETY: This is safe because `Waker::new_unchecked` is the only way
148239 // to initialize `drop` and `data` requiring the user to acknowledge
0 commit comments