@@ -72,10 +72,18 @@ pub struct RawWakerVTable {
7272 /// This function will be called when `wake` is called on the [`Waker`].
7373 /// It must wake up the task associated with this [`RawWaker`].
7474 ///
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.
7778 wake : unsafe fn ( * const ( ) ) ,
7879
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+
7987 /// This function gets called when a [`RawWaker`] gets dropped.
8088 ///
8189 /// The implementation of this function must make sure to release any
@@ -85,8 +93,8 @@ pub struct RawWakerVTable {
8593}
8694
8795impl 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.
9098 ///
9199 /// # `clone`
92100 ///
@@ -103,7 +111,16 @@ impl RawWakerVTable {
103111 /// This function will be called when `wake` is called on the [`Waker`].
104112 /// It must wake up the task associated with this [`RawWaker`].
105113 ///
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
107124 /// pointer.
108125 ///
109126 /// # `drop`
@@ -120,11 +137,13 @@ impl RawWakerVTable {
120137 pub const fn new (
121138 clone : unsafe fn ( * const ( ) ) -> RawWaker ,
122139 wake : unsafe fn ( * const ( ) ) ,
140+ wake_by_ref : unsafe fn ( * const ( ) ) ,
123141 drop : unsafe fn ( * const ( ) ) ,
124142 ) -> Self {
125143 Self {
126144 clone,
127145 wake,
146+ wake_by_ref,
128147 drop,
129148 }
130149 }
@@ -187,14 +206,33 @@ unsafe impl Sync for Waker {}
187206impl Waker {
188207 /// Wake up the task associated with this `Waker`.
189208 #[ inline]
190- pub fn wake ( & self ) {
209+ pub fn wake ( self ) {
191210 // The actual wakeup call is delegated through a virtual function call
192211 // to the implementation which is defined by the executor.
212+ let wake = self . waker . vtable . wake ;
213+ let data = self . waker . data ;
214+
215+ // Don't call `drop` -- the waker will be consumed by `wake`.
216+ crate :: mem:: forget ( self ) ;
193217
194218 // SAFETY: This is safe because `Waker::new_unchecked` is the only way
195219 // to initialize `wake` and `data` requiring the user to acknowledge
196220 // 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 ) }
198236 }
199237
200238 /// Returns `true` if this `Waker` and another `Waker` have awoken the same task.
0 commit comments