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,105 @@ 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 forcing
140+ // the lifetime to be invariant (argument-position lifetimes
141+ // are contravariant while return-position lifetimes are
142+ // covariant).
143+ _marker : PhantomData < fn ( & ' a ( ) ) -> & ' a ( ) > ,
144+ }
145+
146+ impl < ' a > Context < ' a > {
147+ /// Create a new `Context` from a `&Waker`.
148+ #[ inline]
149+ pub fn from_waker ( waker : & ' a Waker ) -> Self {
150+ Context {
151+ waker,
152+ _marker : PhantomData ,
153+ }
154+ }
155+
156+ /// Returns a reference to the `Waker` for the current task.
157+ #[ inline]
158+ pub fn waker ( & self ) -> & ' a Waker {
159+ & self . waker
160+ }
161+ }
162+
163+ impl fmt:: Debug for Context < ' _ > {
164+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
165+ f. debug_struct ( "Context" )
166+ . field ( "waker" , & self . waker )
167+ . finish ( )
168+ }
81169}
82170
83171/// A `Waker` is a handle for waking up a task by notifying its executor that it
@@ -98,6 +186,7 @@ unsafe impl Sync for Waker {}
98186
99187impl Waker {
100188 /// Wake up the task associated with this `Waker`.
189+ #[ inline]
101190 pub fn wake ( & self ) {
102191 // The actual wakeup call is delegated through a virtual function call
103192 // to the implementation which is defined by the executor.
@@ -115,6 +204,7 @@ impl Waker {
115204 /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
116205 ///
117206 /// This function is primarily used for optimization purposes.
207+ #[ inline]
118208 pub fn will_wake ( & self , other : & Waker ) -> bool {
119209 self . waker == other. waker
120210 }
@@ -124,6 +214,7 @@ impl Waker {
124214 /// The behavior of the returned `Waker` is undefined if the contract defined
125215 /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
126216 /// Therefore this method is unsafe.
217+ #[ inline]
127218 pub unsafe fn new_unchecked ( waker : RawWaker ) -> Waker {
128219 Waker {
129220 waker,
@@ -132,6 +223,7 @@ impl Waker {
132223}
133224
134225impl Clone for Waker {
226+ #[ inline]
135227 fn clone ( & self ) -> Self {
136228 Waker {
137229 // SAFETY: This is safe because `Waker::new_unchecked` is the only way
@@ -143,6 +235,7 @@ impl Clone for Waker {
143235}
144236
145237impl Drop for Waker {
238+ #[ inline]
146239 fn drop ( & mut self ) {
147240 // SAFETY: This is safe because `Waker::new_unchecked` is the only way
148241 // to initialize `drop` and `data` requiring the user to acknowledge
0 commit comments