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