core/task/wake.rs
1#![stable(feature = "futures_api", since = "1.36.0")]
2
3use crate::any::Any;
4use crate::marker::PhantomData;
5use crate::mem::{ManuallyDrop, transmute};
6use crate::panic::AssertUnwindSafe;
7use crate::{fmt, ptr};
8
9/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
10/// or a [`LocalWaker`] which provides customized wakeup behavior.
11///
12/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable]
13/// that customizes the behavior of the `RawWaker`.
14///
15/// `RawWaker`s are unsafe to use.
16/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation.
17///
18/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
19/// [`Wake`]: ../../alloc/task/trait.Wake.html
20#[derive(PartialEq, Debug)]
21#[stable(feature = "futures_api", since = "1.36.0")]
22pub struct RawWaker {
23 /// A data pointer, which can be used to store arbitrary data as required
24 /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
25 /// that is associated with the task.
26 /// The value of this field gets passed to all functions that are part of
27 /// the vtable as the first parameter.
28 data: *const (),
29 /// Virtual function pointer table that customizes the behavior of this waker.
30 vtable: &'static RawWakerVTable,
31}
32
33impl RawWaker {
34 /// Creates a new `RawWaker` from the provided `data` pointer and `vtable`.
35 ///
36 /// The `data` pointer can be used to store arbitrary data as required
37 /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
38 /// that is associated with the task.
39 /// The value of this pointer will get passed to all functions that are part
40 /// of the `vtable` as the first parameter.
41 ///
42 /// It is important to consider that the `data` pointer must point to a
43 /// thread safe type such as an `Arc<T: Send + Sync>`
44 /// when used to construct a [`Waker`]. This restriction is lifted when
45 /// constructing a [`LocalWaker`], which allows using types that do not implement
46 /// <code>[Send] + [Sync]</code> like `Rc<T>`.
47 ///
48 /// The `vtable` customizes the behavior of a `Waker` which gets created
49 /// from a `RawWaker`. For each operation on the `Waker`, the associated
50 /// function in the `vtable` of the underlying `RawWaker` will be called.
51 #[inline]
52 #[rustc_promotable]
53 #[stable(feature = "futures_api", since = "1.36.0")]
54 #[rustc_const_stable(feature = "futures_api", since = "1.36.0")]
55 #[must_use]
56 pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
57 RawWaker { data, vtable }
58 }
59
60 #[stable(feature = "noop_waker", since = "1.85.0")]
61 const NOOP: RawWaker = {
62 const VTABLE: RawWakerVTable = RawWakerVTable::new(
63 // Cloning just returns a new no-op raw waker
64 |_| RawWaker::NOOP,
65 // `wake` does nothing
66 |_| {},
67 // `wake_by_ref` does nothing
68 |_| {},
69 // Dropping does nothing as we don't allocate anything
70 |_| {},
71 );
72 RawWaker::new(ptr::null(), &VTABLE)
73 };
74}
75
76/// A virtual function pointer table (vtable) that specifies the behavior
77/// of a [`RawWaker`].
78///
79/// The pointer passed to all functions inside the vtable is the `data` pointer
80/// from the enclosing [`RawWaker`] object.
81///
82/// The functions inside this struct are only intended to be called on the `data`
83/// pointer of a properly constructed [`RawWaker`] object from inside the
84/// [`RawWaker`] implementation. Calling one of the contained functions using
85/// any other `data` pointer will cause undefined behavior.
86///
87/// Note that while this type implements `PartialEq`, comparing function pointers, and hence
88/// comparing structs like this that contain function pointers, is unreliable: pointers to the same
89/// function can compare inequal (because functions are duplicated in multiple codegen units), and
90/// pointers to *different* functions can compare equal (since identical functions can be
91/// deduplicated within a codegen unit).
92///
93/// # Thread safety
94/// If the [`RawWaker`] will be used to construct a [`Waker`] then
95/// these functions must all be thread-safe (even though [`RawWaker`] is
96/// <code>\![Send] + \![Sync]</code>). This is because [`Waker`] is <code>[Send] + [Sync]</code>,
97/// and it may be moved to arbitrary threads or invoked by `&` reference. For example,
98/// this means that if the `clone` and `drop` functions manage a reference count,
99/// they must do so atomically.
100///
101/// However, if the [`RawWaker`] will be used to construct a [`LocalWaker`] instead, then
102/// these functions don't need to be thread safe. This means that <code>\![Send] + \![Sync]</code>
103/// data can be stored in the data pointer, and reference counting does not need any atomic
104/// synchronization. This is because [`LocalWaker`] is not thread safe itself, so it cannot
105/// be sent across threads.
106#[stable(feature = "futures_api", since = "1.36.0")]
107#[allow(unpredictable_function_pointer_comparisons)]
108#[derive(PartialEq, Copy, Clone, Debug)]
109pub struct RawWakerVTable {
110 /// This function will be called when the [`RawWaker`] gets cloned, e.g. when
111 /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned.
112 ///
113 /// The implementation of this function must retain all resources that are
114 /// required for this additional instance of a [`RawWaker`] and associated
115 /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
116 /// of the same task that would have been awoken by the original [`RawWaker`].
117 clone: unsafe fn(*const ()) -> RawWaker,
118
119 /// This function will be called when `wake` is called on the [`Waker`].
120 /// It must wake up the task associated with this [`RawWaker`].
121 ///
122 /// The implementation of this function must make sure to release any
123 /// resources that are associated with this instance of a [`RawWaker`] and
124 /// associated task.
125 wake: unsafe fn(*const ()),
126
127 /// This function will be called when `wake_by_ref` is called on the [`Waker`].
128 /// It must wake up the task associated with this [`RawWaker`].
129 ///
130 /// This function is similar to `wake`, but must not consume the provided data
131 /// pointer.
132 wake_by_ref: unsafe fn(*const ()),
133
134 /// This function will be called when a [`Waker`] gets dropped.
135 ///
136 /// The implementation of this function must make sure to release any
137 /// resources that are associated with this instance of a [`RawWaker`] and
138 /// associated task.
139 drop: unsafe fn(*const ()),
140}
141
142impl RawWakerVTable {
143 /// Creates a new `RawWakerVTable` from the provided `clone`, `wake`,
144 /// `wake_by_ref`, and `drop` functions.
145 ///
146 /// If the [`RawWaker`] will be used to construct a [`Waker`] then
147 /// these functions must all be thread-safe (even though [`RawWaker`] is
148 /// <code>\![Send] + \![Sync]</code>). This is because [`Waker`] is <code>[Send] + [Sync]</code>,
149 /// and it may be moved to arbitrary threads or invoked by `&` reference. For example,
150 /// this means that if the `clone` and `drop` functions manage a reference count,
151 /// they must do so atomically.
152 ///
153 /// However, if the [`RawWaker`] will be used to construct a [`LocalWaker`] instead, then
154 /// these functions don't need to be thread safe. This means that <code>\![Send] + \![Sync]</code>
155 /// data can be stored in the data pointer, and reference counting does not need any atomic
156 /// synchronization. This is because [`LocalWaker`] is not thread safe itself, so it cannot
157 /// be sent across threads.
158 /// # `clone`
159 ///
160 /// This function will be called when the [`RawWaker`] gets cloned, e.g. when
161 /// the [`Waker`]/[`LocalWaker`] in which the [`RawWaker`] is stored gets cloned.
162 ///
163 /// The implementation of this function must retain all resources that are
164 /// required for this additional instance of a [`RawWaker`] and associated
165 /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
166 /// of the same task that would have been awoken by the original [`RawWaker`].
167 ///
168 /// # `wake`
169 ///
170 /// This function will be called when `wake` is called on the [`Waker`].
171 /// It must wake up the task associated with this [`RawWaker`].
172 ///
173 /// The implementation of this function must make sure to release any
174 /// resources that are associated with this instance of a [`RawWaker`] and
175 /// associated task.
176 ///
177 /// # `wake_by_ref`
178 ///
179 /// This function will be called when `wake_by_ref` is called on the [`Waker`].
180 /// It must wake up the task associated with this [`RawWaker`].
181 ///
182 /// This function is similar to `wake`, but must not consume the provided data
183 /// pointer.
184 ///
185 /// # `drop`
186 ///
187 /// This function will be called when a [`Waker`]/[`LocalWaker`] gets
188 /// dropped.
189 ///
190 /// The implementation of this function must make sure to release any
191 /// resources that are associated with this instance of a [`RawWaker`] and
192 /// associated task.
193 #[rustc_promotable]
194 #[stable(feature = "futures_api", since = "1.36.0")]
195 #[rustc_const_stable(feature = "futures_api", since = "1.36.0")]
196 pub const fn new(
197 clone: unsafe fn(*const ()) -> RawWaker,
198 wake: unsafe fn(*const ()),
199 wake_by_ref: unsafe fn(*const ()),
200 drop: unsafe fn(*const ()),
201 ) -> Self {
202 Self { clone, wake, wake_by_ref, drop }
203 }
204}
205
206#[derive(Debug)]
207enum ExtData<'a> {
208 Some(&'a mut dyn Any),
209 None(()),
210}
211
212/// The context of an asynchronous task.
213///
214/// Currently, `Context` only serves to provide access to a [`&Waker`](Waker)
215/// which can be used to wake the current task.
216#[stable(feature = "futures_api", since = "1.36.0")]
217#[lang = "Context"]
218pub struct Context<'a> {
219 waker: &'a Waker,
220 local_waker: &'a LocalWaker,
221 ext: AssertUnwindSafe<ExtData<'a>>,
222 // Ensure we future-proof against variance changes by forcing
223 // the lifetime to be invariant (argument-position lifetimes
224 // are contravariant while return-position lifetimes are
225 // covariant).
226 _marker: PhantomData<fn(&'a ()) -> &'a ()>,
227 // Ensure `Context` is `!Send` and `!Sync` in order to allow
228 // for future `!Send` and / or `!Sync` fields.
229 _marker2: PhantomData<*mut ()>,
230}
231
232impl<'a> Context<'a> {
233 /// Creates a new `Context` from a [`&Waker`](Waker).
234 #[stable(feature = "futures_api", since = "1.36.0")]
235 #[rustc_const_stable(feature = "const_waker", since = "1.82.0")]
236 #[must_use]
237 #[inline]
238 pub const fn from_waker(waker: &'a Waker) -> Self {
239 ContextBuilder::from_waker(waker).build()
240 }
241
242 /// Returns a reference to the [`Waker`] for the current task.
243 #[inline]
244 #[must_use]
245 #[stable(feature = "futures_api", since = "1.36.0")]
246 #[rustc_const_stable(feature = "const_waker", since = "1.82.0")]
247 pub const fn waker(&self) -> &'a Waker {
248 &self.waker
249 }
250
251 /// Returns a reference to the [`LocalWaker`] for the current task.
252 #[inline]
253 #[unstable(feature = "local_waker", issue = "118959")]
254 pub const fn local_waker(&self) -> &'a LocalWaker {
255 &self.local_waker
256 }
257
258 /// Returns a reference to the extension data for the current task.
259 #[inline]
260 #[unstable(feature = "context_ext", issue = "123392")]
261 pub const fn ext(&mut self) -> &mut dyn Any {
262 // FIXME: this field makes Context extra-weird about unwind safety
263 // can we justify AssertUnwindSafe if we stabilize this? do we care?
264 match &mut self.ext.0 {
265 ExtData::Some(data) => *data,
266 ExtData::None(unit) => unit,
267 }
268 }
269}
270
271#[stable(feature = "futures_api", since = "1.36.0")]
272impl fmt::Debug for Context<'_> {
273 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
274 f.debug_struct("Context").field("waker", &self.waker).finish()
275 }
276}
277
278/// A Builder used to construct a `Context` instance
279/// with support for `LocalWaker`.
280///
281/// # Examples
282/// ```
283/// #![feature(local_waker)]
284/// use std::task::{ContextBuilder, LocalWaker, Waker, Poll};
285/// use std::future::Future;
286///
287/// let local_waker = LocalWaker::noop();
288/// let waker = Waker::noop();
289///
290/// let mut cx = ContextBuilder::from_waker(&waker)
291/// .local_waker(&local_waker)
292/// .build();
293///
294/// let mut future = std::pin::pin!(async { 20 });
295/// let poll = future.as_mut().poll(&mut cx);
296/// assert_eq!(poll, Poll::Ready(20));
297///
298/// ```
299#[unstable(feature = "local_waker", issue = "118959")]
300#[derive(Debug)]
301pub struct ContextBuilder<'a> {
302 waker: &'a Waker,
303 local_waker: &'a LocalWaker,
304 ext: ExtData<'a>,
305 // Ensure we future-proof against variance changes by forcing
306 // the lifetime to be invariant (argument-position lifetimes
307 // are contravariant while return-position lifetimes are
308 // covariant).
309 _marker: PhantomData<fn(&'a ()) -> &'a ()>,
310 // Ensure `Context` is `!Send` and `!Sync` in order to allow
311 // for future `!Send` and / or `!Sync` fields.
312 _marker2: PhantomData<*mut ()>,
313}
314
315impl<'a> ContextBuilder<'a> {
316 /// Creates a ContextBuilder from a Waker.
317 #[inline]
318 #[unstable(feature = "local_waker", issue = "118959")]
319 pub const fn from_waker(waker: &'a Waker) -> Self {
320 // SAFETY: LocalWaker is just Waker without thread safety
321 let local_waker = unsafe { transmute(waker) };
322 Self {
323 waker,
324 local_waker,
325 ext: ExtData::None(()),
326 _marker: PhantomData,
327 _marker2: PhantomData,
328 }
329 }
330
331 /// Creates a ContextBuilder from an existing Context.
332 #[inline]
333 #[unstable(feature = "context_ext", issue = "123392")]
334 pub const fn from(cx: &'a mut Context<'_>) -> Self {
335 let ext = match &mut cx.ext.0 {
336 ExtData::Some(ext) => ExtData::Some(*ext),
337 ExtData::None(()) => ExtData::None(()),
338 };
339 Self {
340 waker: cx.waker,
341 local_waker: cx.local_waker,
342 ext,
343 _marker: PhantomData,
344 _marker2: PhantomData,
345 }
346 }
347
348 /// Sets the value for the waker on `Context`.
349 #[inline]
350 #[unstable(feature = "context_ext", issue = "123392")]
351 pub const fn waker(self, waker: &'a Waker) -> Self {
352 Self { waker, ..self }
353 }
354
355 /// Sets the value for the local waker on `Context`.
356 #[inline]
357 #[unstable(feature = "local_waker", issue = "118959")]
358 pub const fn local_waker(self, local_waker: &'a LocalWaker) -> Self {
359 Self { local_waker, ..self }
360 }
361
362 /// Sets the value for the extension data on `Context`.
363 #[inline]
364 #[unstable(feature = "context_ext", issue = "123392")]
365 pub const fn ext(self, data: &'a mut dyn Any) -> Self {
366 Self { ext: ExtData::Some(data), ..self }
367 }
368
369 /// Builds the `Context`.
370 #[inline]
371 #[unstable(feature = "local_waker", issue = "118959")]
372 pub const fn build(self) -> Context<'a> {
373 let ContextBuilder { waker, local_waker, ext, _marker, _marker2 } = self;
374 Context { waker, local_waker, ext: AssertUnwindSafe(ext), _marker, _marker2 }
375 }
376}
377
378/// A `Waker` is a handle for waking up a task by notifying its executor that it
379/// is ready to be run.
380///
381/// This handle encapsulates a [`RawWaker`] instance, which defines the
382/// executor-specific wakeup behavior.
383///
384/// The typical life of a `Waker` is that it is constructed by an executor, wrapped in a
385/// [`Context`], then passed to [`Future::poll()`]. Then, if the future chooses to return
386/// [`Poll::Pending`], it must also store the waker somehow and call [`Waker::wake()`] when
387/// the future should be polled again.
388///
389/// Implements [`Clone`], [`Send`], and [`Sync`]; therefore, a waker may be invoked
390/// from any thread, including ones not in any way managed by the executor. For example,
391/// this might be done to wake a future when a blocking function call completes on another
392/// thread.
393///
394/// Note that it is preferable to use `waker.clone_from(&new_waker)` instead
395/// of `*waker = new_waker.clone()`, as the former will avoid cloning the waker
396/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
397///
398/// Constructing a `Waker` from a [`RawWaker`] is unsafe.
399/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation.
400///
401/// [`Future::poll()`]: core::future::Future::poll
402/// [`Poll::Pending`]: core::task::Poll::Pending
403/// [`Wake`]: ../../alloc/task/trait.Wake.html
404#[repr(transparent)]
405#[stable(feature = "futures_api", since = "1.36.0")]
406#[rustc_diagnostic_item = "Waker"]
407pub struct Waker {
408 waker: RawWaker,
409}
410
411#[stable(feature = "futures_api", since = "1.36.0")]
412impl Unpin for Waker {}
413#[stable(feature = "futures_api", since = "1.36.0")]
414unsafe impl Send for Waker {}
415#[stable(feature = "futures_api", since = "1.36.0")]
416unsafe impl Sync for Waker {}
417
418impl Waker {
419 /// Wakes up the task associated with this `Waker`.
420 ///
421 /// As long as the executor keeps running and the task is not finished, it is
422 /// guaranteed that each invocation of [`wake()`](Self::wake) (or
423 /// [`wake_by_ref()`](Self::wake_by_ref)) will be followed by at least one
424 /// [`poll()`] of the task to which this `Waker` belongs. This makes
425 /// it possible to temporarily yield to other tasks while running potentially
426 /// unbounded processing loops.
427 ///
428 /// Note that the above implies that multiple wake-ups may be coalesced into a
429 /// single [`poll()`] invocation by the runtime.
430 ///
431 /// Also note that yielding to competing tasks is not guaranteed: it is the
432 /// executor’s choice which task to run and the executor may choose to run the
433 /// current task again.
434 ///
435 /// [`poll()`]: crate::future::Future::poll
436 #[inline]
437 #[stable(feature = "futures_api", since = "1.36.0")]
438 pub fn wake(self) {
439 // The actual wakeup call is delegated through a virtual function call
440 // to the implementation which is defined by the executor.
441
442 // Don't call `drop` -- the waker will be consumed by `wake`.
443 let this = ManuallyDrop::new(self);
444
445 // SAFETY: This is safe because `Waker::from_raw` is the only way
446 // to initialize `wake` and `data` requiring the user to acknowledge
447 // that the contract of `RawWaker` is upheld.
448 unsafe { (this.waker.vtable.wake)(this.waker.data) };
449 }
450
451 /// Wakes up the task associated with this `Waker` without consuming the `Waker`.
452 ///
453 /// This is similar to [`wake()`](Self::wake), but may be slightly less efficient in
454 /// the case where an owned `Waker` is available. This method should be preferred to
455 /// calling `waker.clone().wake()`.
456 #[inline]
457 #[stable(feature = "futures_api", since = "1.36.0")]
458 pub fn wake_by_ref(&self) {
459 // The actual wakeup call is delegated through a virtual function call
460 // to the implementation which is defined by the executor.
461
462 // SAFETY: see `wake`
463 unsafe { (self.waker.vtable.wake_by_ref)(self.waker.data) }
464 }
465
466 /// Returns `true` if this `Waker` and another `Waker` would awake the same task.
467 ///
468 /// This function works on a best-effort basis, and may return false even
469 /// when the `Waker`s would awaken the same task. However, if this function
470 /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
471 ///
472 /// This function is primarily used for optimization purposes — for example,
473 /// this type's [`clone_from`](Self::clone_from) implementation uses it to
474 /// avoid cloning the waker when they would wake the same task anyway.
475 #[inline]
476 #[must_use]
477 #[stable(feature = "futures_api", since = "1.36.0")]
478 pub fn will_wake(&self, other: &Waker) -> bool {
479 // We optimize this by comparing vtable addresses instead of vtable contents.
480 // This is permitted since the function is documented as best-effort.
481 let RawWaker { data: a_data, vtable: a_vtable } = self.waker;
482 let RawWaker { data: b_data, vtable: b_vtable } = other.waker;
483 a_data == b_data && ptr::eq(a_vtable, b_vtable)
484 }
485
486 /// Creates a new `Waker` from the provided `data` pointer and `vtable`.
487 ///
488 /// The `data` pointer can be used to store arbitrary data as required
489 /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
490 /// that is associated with the task.
491 /// The value of this pointer will get passed to all functions that are part
492 /// of the `vtable` as the first parameter.
493 ///
494 /// It is important to consider that the `data` pointer must point to a
495 /// thread safe type such as an `Arc`.
496 ///
497 /// The `vtable` customizes the behavior of a `Waker`. For each operation
498 /// on the `Waker`, the associated function in the `vtable` will be called.
499 ///
500 /// # Safety
501 ///
502 /// The behavior of the returned `Waker` is undefined if the contract defined
503 /// in [`RawWakerVTable`]'s documentation is not upheld.
504 ///
505 /// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the
506 /// cost of a required heap allocation.)
507 ///
508 /// [`Wake`]: ../../alloc/task/trait.Wake.html
509 #[inline]
510 #[must_use]
511 #[stable(feature = "waker_getters", since = "1.83.0")]
512 #[rustc_const_stable(feature = "waker_getters", since = "1.83.0")]
513 pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self {
514 Waker { waker: RawWaker { data, vtable } }
515 }
516
517 /// Creates a new `Waker` from [`RawWaker`].
518 ///
519 /// # Safety
520 ///
521 /// The behavior of the returned `Waker` is undefined if the contract defined
522 /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
523 ///
524 /// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the
525 /// cost of a required heap allocation.)
526 ///
527 /// [`Wake`]: ../../alloc/task/trait.Wake.html
528 #[inline]
529 #[must_use]
530 #[stable(feature = "futures_api", since = "1.36.0")]
531 #[rustc_const_stable(feature = "const_waker", since = "1.82.0")]
532 pub const unsafe fn from_raw(waker: RawWaker) -> Waker {
533 Waker { waker }
534 }
535
536 /// Returns a reference to a `Waker` that does nothing when used.
537 ///
538 // Note! Much of the documentation for this method is duplicated
539 // in the docs for `LocalWaker::noop`.
540 // If you edit it, consider editing the other copy too.
541 //
542 /// This is mostly useful for writing tests that need a [`Context`] to poll
543 /// some futures, but are not expecting those futures to wake the waker or
544 /// do not need to do anything specific if it happens.
545 ///
546 /// More generally, using `Waker::noop()` to poll a future
547 /// means discarding the notification of when the future should be polled again.
548 /// So it should only be used when such a notification will not be needed to make progress.
549 ///
550 /// If an owned `Waker` is needed, `clone()` this one.
551 ///
552 /// # Examples
553 ///
554 /// ```
555 /// use std::future::Future;
556 /// use std::task;
557 ///
558 /// let mut cx = task::Context::from_waker(task::Waker::noop());
559 ///
560 /// let mut future = Box::pin(async { 10 });
561 /// assert_eq!(future.as_mut().poll(&mut cx), task::Poll::Ready(10));
562 /// ```
563 #[inline]
564 #[must_use]
565 #[stable(feature = "noop_waker", since = "1.85.0")]
566 #[rustc_const_stable(feature = "noop_waker", since = "1.85.0")]
567 pub const fn noop() -> &'static Waker {
568 const WAKER: &Waker = &Waker { waker: RawWaker::NOOP };
569 WAKER
570 }
571
572 /// Gets the `data` pointer used to create this `Waker`.
573 #[inline]
574 #[must_use]
575 #[stable(feature = "waker_getters", since = "1.83.0")]
576 pub fn data(&self) -> *const () {
577 self.waker.data
578 }
579
580 /// Gets the `vtable` pointer used to create this `Waker`.
581 #[inline]
582 #[must_use]
583 #[stable(feature = "waker_getters", since = "1.83.0")]
584 pub fn vtable(&self) -> &'static RawWakerVTable {
585 self.waker.vtable
586 }
587}
588
589#[stable(feature = "futures_api", since = "1.36.0")]
590impl Clone for Waker {
591 #[inline]
592 fn clone(&self) -> Self {
593 Waker {
594 // SAFETY: This is safe because `Waker::from_raw` is the only way
595 // to initialize `clone` and `data` requiring the user to acknowledge
596 // that the contract of [`RawWaker`] is upheld.
597 waker: unsafe { (self.waker.vtable.clone)(self.waker.data) },
598 }
599 }
600
601 /// Assigns a clone of `source` to `self`, unless [`self.will_wake(source)`][Waker::will_wake] anyway.
602 ///
603 /// This method is preferred over simply assigning `source.clone()` to `self`,
604 /// as it avoids cloning the waker if `self` is already the same waker.
605 ///
606 /// # Examples
607 ///
608 /// ```
609 /// use std::future::Future;
610 /// use std::pin::Pin;
611 /// use std::sync::{Arc, Mutex};
612 /// use std::task::{Context, Poll, Waker};
613 ///
614 /// struct Waiter {
615 /// shared: Arc<Mutex<Shared>>,
616 /// }
617 ///
618 /// struct Shared {
619 /// waker: Waker,
620 /// // ...
621 /// }
622 ///
623 /// impl Future for Waiter {
624 /// type Output = ();
625 /// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
626 /// let mut shared = self.shared.lock().unwrap();
627 ///
628 /// // update the waker
629 /// shared.waker.clone_from(cx.waker());
630 ///
631 /// // readiness logic ...
632 /// # Poll::Ready(())
633 /// }
634 /// }
635 ///
636 /// ```
637 #[inline]
638 fn clone_from(&mut self, source: &Self) {
639 if !self.will_wake(source) {
640 *self = source.clone();
641 }
642 }
643}
644
645#[stable(feature = "futures_api", since = "1.36.0")]
646impl Drop for Waker {
647 #[inline]
648 fn drop(&mut self) {
649 // SAFETY: This is safe because `Waker::from_raw` is the only way
650 // to initialize `drop` and `data` requiring the user to acknowledge
651 // that the contract of `RawWaker` is upheld.
652 unsafe { (self.waker.vtable.drop)(self.waker.data) }
653 }
654}
655
656#[stable(feature = "futures_api", since = "1.36.0")]
657impl fmt::Debug for Waker {
658 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
659 let vtable_ptr = self.waker.vtable as *const RawWakerVTable;
660 f.debug_struct("Waker")
661 .field("data", &self.waker.data)
662 .field("vtable", &vtable_ptr)
663 .finish()
664 }
665}
666
667/// A `LocalWaker` is analogous to a [`Waker`], but it does not implement [`Send`] or [`Sync`].
668///
669/// This handle encapsulates a [`RawWaker`] instance, which defines the
670/// executor-specific wakeup behavior.
671///
672/// Local wakers can be requested from a `Context` with the [`local_waker`] method.
673///
674/// The typical life of a `LocalWaker` is that it is constructed by an executor, wrapped in a
675/// [`Context`] using [`ContextBuilder`], then passed to [`Future::poll()`]. Then, if the future chooses to return
676/// [`Poll::Pending`], it must also store the waker somehow and call [`LocalWaker::wake()`] when
677/// the future should be polled again.
678///
679/// Implements [`Clone`], but neither [`Send`] nor [`Sync`]; therefore, a local waker may
680/// not be moved to other threads. In general, when deciding to use wakers or local wakers,
681/// local wakers are preferable unless the waker needs to be sent across threads. This is because
682/// wakers can incur in additional cost related to memory synchronization.
683///
684/// Note that it is preferable to use `local_waker.clone_from(&new_waker)` instead
685/// of `*local_waker = new_waker.clone()`, as the former will avoid cloning the waker
686/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
687///
688/// # Examples
689/// Usage of a local waker to implement a future analogous to `std::thread::yield_now()`.
690/// ```
691/// #![feature(local_waker)]
692/// use std::future::{Future, poll_fn};
693/// use std::task::Poll;
694///
695/// // a future that returns pending once.
696/// fn yield_now() -> impl Future<Output=()> + Unpin {
697/// let mut yielded = false;
698/// poll_fn(move |cx| {
699/// if !yielded {
700/// yielded = true;
701/// cx.local_waker().wake_by_ref();
702/// return Poll::Pending;
703/// }
704/// return Poll::Ready(())
705/// })
706/// }
707///
708/// # async fn __() {
709/// yield_now().await;
710/// # }
711/// ```
712///
713/// [`Future::poll()`]: core::future::Future::poll
714/// [`Poll::Pending`]: core::task::Poll::Pending
715/// [`local_waker`]: core::task::Context::local_waker
716#[unstable(feature = "local_waker", issue = "118959")]
717#[repr(transparent)]
718pub struct LocalWaker {
719 waker: RawWaker,
720}
721
722#[unstable(feature = "local_waker", issue = "118959")]
723impl Unpin for LocalWaker {}
724
725impl LocalWaker {
726 /// Wakes up the task associated with this `LocalWaker`.
727 ///
728 /// As long as the executor keeps running and the task is not finished, it is
729 /// guaranteed that each invocation of [`wake()`](Self::wake) (or
730 /// [`wake_by_ref()`](Self::wake_by_ref)) will be followed by at least one
731 /// [`poll()`] of the task to which this `LocalWaker` belongs. This makes
732 /// it possible to temporarily yield to other tasks while running potentially
733 /// unbounded processing loops.
734 ///
735 /// Note that the above implies that multiple wake-ups may be coalesced into a
736 /// single [`poll()`] invocation by the runtime.
737 ///
738 /// Also note that yielding to competing tasks is not guaranteed: it is the
739 /// executor’s choice which task to run and the executor may choose to run the
740 /// current task again.
741 ///
742 /// [`poll()`]: crate::future::Future::poll
743 #[inline]
744 #[unstable(feature = "local_waker", issue = "118959")]
745 pub fn wake(self) {
746 // The actual wakeup call is delegated through a virtual function call
747 // to the implementation which is defined by the executor.
748
749 // Don't call `drop` -- the waker will be consumed by `wake`.
750 let this = ManuallyDrop::new(self);
751
752 // SAFETY: This is safe because `Waker::from_raw` is the only way
753 // to initialize `wake` and `data` requiring the user to acknowledge
754 // that the contract of `RawWaker` is upheld.
755 unsafe { (this.waker.vtable.wake)(this.waker.data) };
756 }
757
758 /// Wakes up the task associated with this `LocalWaker` without consuming the `LocalWaker`.
759 ///
760 /// This is similar to [`wake()`](Self::wake), but may be slightly less efficient in
761 /// the case where an owned `Waker` is available. This method should be preferred to
762 /// calling `waker.clone().wake()`.
763 #[inline]
764 #[unstable(feature = "local_waker", issue = "118959")]
765 pub fn wake_by_ref(&self) {
766 // The actual wakeup call is delegated through a virtual function call
767 // to the implementation which is defined by the executor.
768
769 // SAFETY: see `wake`
770 unsafe { (self.waker.vtable.wake_by_ref)(self.waker.data) }
771 }
772
773 /// Returns `true` if this `LocalWaker` and another `LocalWaker` would awake the same task.
774 ///
775 /// This function works on a best-effort basis, and may return false even
776 /// when the `Waker`s would awaken the same task. However, if this function
777 /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
778 ///
779 /// This function is primarily used for optimization purposes — for example,
780 /// this type's [`clone_from`](Self::clone_from) implementation uses it to
781 /// avoid cloning the waker when they would wake the same task anyway.
782 #[inline]
783 #[must_use]
784 #[unstable(feature = "local_waker", issue = "118959")]
785 pub fn will_wake(&self, other: &LocalWaker) -> bool {
786 // We optimize this by comparing vtable addresses instead of vtable contents.
787 // This is permitted since the function is documented as best-effort.
788 let RawWaker { data: a_data, vtable: a_vtable } = self.waker;
789 let RawWaker { data: b_data, vtable: b_vtable } = other.waker;
790 a_data == b_data && ptr::eq(a_vtable, b_vtable)
791 }
792
793 /// Creates a new `LocalWaker` from the provided `data` pointer and `vtable`.
794 ///
795 /// The `data` pointer can be used to store arbitrary data as required
796 /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
797 /// that is associated with the task.
798 /// The value of this pointer will get passed to all functions that are part
799 /// of the `vtable` as the first parameter.
800 ///
801 /// The `vtable` customizes the behavior of a `LocalWaker`. For each
802 /// operation on the `LocalWaker`, the associated function in the `vtable`
803 /// will be called.
804 ///
805 /// # Safety
806 ///
807 /// The behavior of the returned `Waker` is undefined if the contract defined
808 /// in [`RawWakerVTable`]'s documentation is not upheld.
809 ///
810 #[inline]
811 #[must_use]
812 #[unstable(feature = "local_waker", issue = "118959")]
813 pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self {
814 LocalWaker { waker: RawWaker { data, vtable } }
815 }
816
817 /// Creates a new `LocalWaker` from [`RawWaker`].
818 ///
819 /// The behavior of the returned `LocalWaker` is undefined if the contract defined
820 /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
821 /// Therefore this method is unsafe.
822 #[inline]
823 #[must_use]
824 #[unstable(feature = "local_waker", issue = "118959")]
825 pub const unsafe fn from_raw(waker: RawWaker) -> LocalWaker {
826 Self { waker }
827 }
828
829 /// Returns a reference to a `LocalWaker` that does nothing when used.
830 ///
831 // Note! Much of the documentation for this method is duplicated
832 // in the docs for `Waker::noop`.
833 // If you edit it, consider editing the other copy too.
834 //
835 /// This is mostly useful for writing tests that need a [`Context`] to poll
836 /// some futures, but are not expecting those futures to wake the waker or
837 /// do not need to do anything specific if it happens.
838 ///
839 /// More generally, using `LocalWaker::noop()` to poll a future
840 /// means discarding the notification of when the future should be polled again,
841 /// So it should only be used when such a notification will not be needed to make progress.
842 ///
843 /// If an owned `LocalWaker` is needed, `clone()` this one.
844 ///
845 /// # Examples
846 ///
847 /// ```
848 /// #![feature(local_waker)]
849 /// use std::future::Future;
850 /// use std::task::{ContextBuilder, LocalWaker, Waker, Poll};
851 ///
852 /// let mut cx = ContextBuilder::from_waker(Waker::noop())
853 /// .local_waker(LocalWaker::noop())
854 /// .build();
855 ///
856 /// let mut future = Box::pin(async { 10 });
857 /// assert_eq!(future.as_mut().poll(&mut cx), Poll::Ready(10));
858 /// ```
859 #[inline]
860 #[must_use]
861 #[unstable(feature = "local_waker", issue = "118959")]
862 pub const fn noop() -> &'static LocalWaker {
863 const WAKER: &LocalWaker = &LocalWaker { waker: RawWaker::NOOP };
864 WAKER
865 }
866
867 /// Gets the `data` pointer used to create this `LocalWaker`.
868 #[inline]
869 #[must_use]
870 #[unstable(feature = "local_waker", issue = "118959")]
871 pub fn data(&self) -> *const () {
872 self.waker.data
873 }
874
875 /// Gets the `vtable` pointer used to create this `LocalWaker`.
876 #[inline]
877 #[must_use]
878 #[unstable(feature = "local_waker", issue = "118959")]
879 pub fn vtable(&self) -> &'static RawWakerVTable {
880 self.waker.vtable
881 }
882}
883#[unstable(feature = "local_waker", issue = "118959")]
884impl Clone for LocalWaker {
885 #[inline]
886 fn clone(&self) -> Self {
887 LocalWaker {
888 // SAFETY: This is safe because `Waker::from_raw` is the only way
889 // to initialize `clone` and `data` requiring the user to acknowledge
890 // that the contract of [`RawWaker`] is upheld.
891 waker: unsafe { (self.waker.vtable.clone)(self.waker.data) },
892 }
893 }
894
895 #[inline]
896 fn clone_from(&mut self, source: &Self) {
897 if !self.will_wake(source) {
898 *self = source.clone();
899 }
900 }
901}
902
903#[unstable(feature = "local_waker", issue = "118959")]
904impl AsRef<LocalWaker> for Waker {
905 fn as_ref(&self) -> &LocalWaker {
906 // SAFETY: LocalWaker is just Waker without thread safety
907 unsafe { transmute(self) }
908 }
909}
910
911#[unstable(feature = "local_waker", issue = "118959")]
912impl Drop for LocalWaker {
913 #[inline]
914 fn drop(&mut self) {
915 // SAFETY: This is safe because `LocalWaker::from_raw` is the only way
916 // to initialize `drop` and `data` requiring the user to acknowledge
917 // that the contract of `RawWaker` is upheld.
918 unsafe { (self.waker.vtable.drop)(self.waker.data) }
919 }
920}
921
922#[unstable(feature = "local_waker", issue = "118959")]
923impl fmt::Debug for LocalWaker {
924 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
925 let vtable_ptr = self.waker.vtable as *const RawWakerVTable;
926 f.debug_struct("LocalWaker")
927 .field("data", &self.waker.data)
928 .field("vtable", &vtable_ptr)
929 .finish()
930 }
931}
932
933#[unstable(feature = "local_waker", issue = "118959")]
934impl !Send for LocalWaker {}
935#[unstable(feature = "local_waker", issue = "118959")]
936impl !Sync for LocalWaker {}