3
3
issue = "50547" ) ]
4
4
5
5
use fmt;
6
- use marker:: Unpin ;
6
+ use marker:: { PhantomData , Unpin } ;
7
7
8
8
/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
9
9
/// which provides customized wakeup behavior.
@@ -36,6 +36,10 @@ impl RawWaker {
36
36
/// The `vtable` customizes the behavior of a `Waker` which gets created
37
37
/// from a `RawWaker`. For each operation on the `Waker`, the associated
38
38
/// 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" ) ]
39
43
pub const fn new ( data : * const ( ) , vtable : & ' static RawWakerVTable ) -> RawWaker {
40
44
RawWaker {
41
45
data,
@@ -63,21 +67,105 @@ pub struct RawWakerVTable {
63
67
/// required for this additional instance of a [`RawWaker`] and associated
64
68
/// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
65
69
/// 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 ,
67
71
68
72
/// This function will be called when `wake` is called on the [`Waker`].
69
73
/// It must wake up the task associated with this [`RawWaker`].
70
74
///
71
75
/// The implemention of this function must not consume the provided data
72
76
/// 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
+ }
74
86
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
+ ///
75
111
/// This function gets called when a [`RawWaker`] gets dropped.
76
112
///
77
113
/// The implementation of this function must make sure to release any
78
114
/// resources that are associated with this instance of a [`RawWaker`] and
79
115
/// 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
+ }
81
169
}
82
170
83
171
/// 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 {}
98
186
99
187
impl Waker {
100
188
/// Wake up the task associated with this `Waker`.
189
+ #[ inline]
101
190
pub fn wake ( & self ) {
102
191
// The actual wakeup call is delegated through a virtual function call
103
192
// to the implementation which is defined by the executor.
@@ -115,6 +204,7 @@ impl Waker {
115
204
/// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
116
205
///
117
206
/// This function is primarily used for optimization purposes.
207
+ #[ inline]
118
208
pub fn will_wake ( & self , other : & Waker ) -> bool {
119
209
self . waker == other. waker
120
210
}
@@ -124,6 +214,7 @@ impl Waker {
124
214
/// The behavior of the returned `Waker` is undefined if the contract defined
125
215
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
126
216
/// Therefore this method is unsafe.
217
+ #[ inline]
127
218
pub unsafe fn new_unchecked ( waker : RawWaker ) -> Waker {
128
219
Waker {
129
220
waker,
@@ -132,6 +223,7 @@ impl Waker {
132
223
}
133
224
134
225
impl Clone for Waker {
226
+ #[ inline]
135
227
fn clone ( & self ) -> Self {
136
228
Waker {
137
229
// SAFETY: This is safe because `Waker::new_unchecked` is the only way
@@ -143,6 +235,7 @@ impl Clone for Waker {
143
235
}
144
236
145
237
impl Drop for Waker {
238
+ #[ inline]
146
239
fn drop ( & mut self ) {
147
240
// SAFETY: This is safe because `Waker::new_unchecked` is the only way
148
241
// to initialize `drop` and `data` requiring the user to acknowledge
0 commit comments