@@ -72,10 +72,18 @@ pub struct RawWakerVTable {
72
72
/// This function will be called when `wake` is called on the [`Waker`].
73
73
/// It must wake up the task associated with this [`RawWaker`].
74
74
///
75
- /// The implemention of this function must not consume the provided data
76
- /// pointer.
75
+ /// The implementation of this function must make sure to release any
76
+ /// resources that are associated with this instance of a [`RawWaker`] and
77
+ /// associated task.
77
78
wake : unsafe fn ( * const ( ) ) ,
78
79
80
+ /// This function will be called when `wake_by_ref` is called on the [`Waker`].
81
+ /// It must wake up the task associated with this [`RawWaker`].
82
+ ///
83
+ /// This function is similar to `wake`, but must not consume the provided data
84
+ /// pointer.
85
+ wake_by_ref : unsafe fn ( * const ( ) ) ,
86
+
79
87
/// This function gets called when a [`RawWaker`] gets dropped.
80
88
///
81
89
/// The implementation of this function must make sure to release any
@@ -85,8 +93,8 @@ pub struct RawWakerVTable {
85
93
}
86
94
87
95
impl RawWakerVTable {
88
- /// Creates a new `RawWakerVTable` from the provided `clone`, `wake`, and
89
- /// `drop` functions.
96
+ /// Creates a new `RawWakerVTable` from the provided `clone`, `wake`,
97
+ /// `wake_by_ref`, and ` drop` functions.
90
98
///
91
99
/// # `clone`
92
100
///
@@ -103,7 +111,16 @@ impl RawWakerVTable {
103
111
/// This function will be called when `wake` is called on the [`Waker`].
104
112
/// It must wake up the task associated with this [`RawWaker`].
105
113
///
106
- /// The implemention of this function must not consume the provided data
114
+ /// The implementation of this function must make sure to release any
115
+ /// resources that are associated with this instance of a [`RawWaker`] and
116
+ /// associated task.
117
+ ///
118
+ /// # `wake_by_ref`
119
+ ///
120
+ /// This function will be called when `wake_by_ref` is called on the [`Waker`].
121
+ /// It must wake up the task associated with this [`RawWaker`].
122
+ ///
123
+ /// This function is similar to `wake`, but must not consume the provided data
107
124
/// pointer.
108
125
///
109
126
/// # `drop`
@@ -120,11 +137,13 @@ impl RawWakerVTable {
120
137
pub const fn new (
121
138
clone : unsafe fn ( * const ( ) ) -> RawWaker ,
122
139
wake : unsafe fn ( * const ( ) ) ,
140
+ wake_by_ref : unsafe fn ( * const ( ) ) ,
123
141
drop : unsafe fn ( * const ( ) ) ,
124
142
) -> Self {
125
143
Self {
126
144
clone,
127
145
wake,
146
+ wake_by_ref,
128
147
drop,
129
148
}
130
149
}
@@ -187,14 +206,33 @@ unsafe impl Sync for Waker {}
187
206
impl Waker {
188
207
/// Wake up the task associated with this `Waker`.
189
208
#[ inline]
190
- pub fn wake ( & self ) {
209
+ pub fn wake ( self ) {
191
210
// The actual wakeup call is delegated through a virtual function call
192
211
// to the implementation which is defined by the executor.
212
+ let wake = self . waker . vtable . wake ;
213
+ let data = self . waker . data ;
193
214
194
- // SAFETY: This is safe because `Waker::new_unchecked` is the only way
215
+ // Don't call `drop` -- the waker will be consumed by `wake`.
216
+ crate :: mem:: forget ( self ) ;
217
+
218
+ // SAFETY: This is safe because `Waker::from_raw` is the only way
195
219
// to initialize `wake` and `data` requiring the user to acknowledge
196
220
// that the contract of `RawWaker` is upheld.
197
- unsafe { ( self . waker . vtable . wake ) ( self . waker . data ) }
221
+ unsafe { ( wake) ( data) } ;
222
+ }
223
+
224
+ /// Wake up the task associated with this `Waker` without consuming the `Waker`.
225
+ ///
226
+ /// This is similar to `wake`, but may be slightly less efficient in the case
227
+ /// where an owned `Waker` is available. This method should be preferred to
228
+ /// calling `waker.clone().wake()`.
229
+ #[ inline]
230
+ pub fn wake_by_ref ( & self ) {
231
+ // The actual wakeup call is delegated through a virtual function call
232
+ // to the implementation which is defined by the executor.
233
+
234
+ // SAFETY: see `wake`
235
+ unsafe { ( self . waker . vtable . wake_by_ref ) ( self . waker . data ) }
198
236
}
199
237
200
238
/// Returns `true` if this `Waker` and another `Waker` have awoken the same task.
@@ -215,7 +253,7 @@ impl Waker {
215
253
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
216
254
/// Therefore this method is unsafe.
217
255
#[ inline]
218
- pub unsafe fn new_unchecked ( waker : RawWaker ) -> Waker {
256
+ pub unsafe fn from_raw ( waker : RawWaker ) -> Waker {
219
257
Waker {
220
258
waker,
221
259
}
@@ -226,7 +264,7 @@ impl Clone for Waker {
226
264
#[ inline]
227
265
fn clone ( & self ) -> Self {
228
266
Waker {
229
- // SAFETY: This is safe because `Waker::new_unchecked ` is the only way
267
+ // SAFETY: This is safe because `Waker::from_raw ` is the only way
230
268
// to initialize `clone` and `data` requiring the user to acknowledge
231
269
// that the contract of [`RawWaker`] is upheld.
232
270
waker : unsafe { ( self . waker . vtable . clone ) ( self . waker . data ) } ,
@@ -237,7 +275,7 @@ impl Clone for Waker {
237
275
impl Drop for Waker {
238
276
#[ inline]
239
277
fn drop ( & mut self ) {
240
- // SAFETY: This is safe because `Waker::new_unchecked ` is the only way
278
+ // SAFETY: This is safe because `Waker::from_raw ` is the only way
241
279
// to initialize `drop` and `data` requiring the user to acknowledge
242
280
// that the contract of `RawWaker` is upheld.
243
281
unsafe { ( self . waker . vtable . drop ) ( self . waker . data ) }
0 commit comments