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,
422 /// it is 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, such that the call to
425 /// [`wake()`](Self::wake) (or [`wake_by_ref()`](Self::wake_by_ref)) _happens-before_
426 /// the beginning of the invocation of [`poll()`]. This makes it possible to temporarily
427 /// yield to other tasks while running potentially unbounded processing loops.
428 ///
429 /// Note that the above implies that multiple wake-ups may be coalesced into a
430 /// single [`poll()`] invocation by the executor.
431 ///
432 /// Also note that yielding to competing tasks is not guaranteed: it is the
433 /// executor’s choice which task to run and the executor may choose to run the
434 /// current task again.
435 ///
436 /// [`poll()`]: crate::future::Future::poll
437 #[inline]
438 #[stable(feature = "futures_api", since = "1.36.0")]
439 pub fn wake(self) {
440 // The actual wakeup call is delegated through a virtual function call
441 // to the implementation which is defined by the executor.
442
443 // Don't call `drop` -- the waker will be consumed by `wake`.
444 let this = ManuallyDrop::new(self);
445
446 // SAFETY: This is safe because `Waker::from_raw` is the only way
447 // to initialize `wake` and `data` requiring the user to acknowledge
448 // that the contract of `RawWaker` is upheld.
449 unsafe { (this.waker.vtable.wake)(this.waker.data) };
450 }
451
452 /// Wakes up the task associated with this `Waker` without consuming the `Waker`.
453 ///
454 /// This is similar to [`wake()`](Self::wake), but may be slightly less efficient in
455 /// the case where an owned `Waker` is available. This method should be preferred to
456 /// calling `waker.clone().wake()`.
457 #[inline]
458 #[stable(feature = "futures_api", since = "1.36.0")]
459 pub fn wake_by_ref(&self) {
460 // The actual wakeup call is delegated through a virtual function call
461 // to the implementation which is defined by the executor.
462
463 // SAFETY: see `wake`
464 unsafe { (self.waker.vtable.wake_by_ref)(self.waker.data) }
465 }
466
467 /// Returns `true` if this `Waker` and another `Waker` would awake the same task.
468 ///
469 /// This function works on a best-effort basis, and may return false even
470 /// when the `Waker`s would awaken the same task. However, if this function
471 /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
472 ///
473 /// This function is primarily used for optimization purposes — for example,
474 /// this type's [`clone_from`](Self::clone_from) implementation uses it to
475 /// avoid cloning the waker when they would wake the same task anyway.
476 #[inline]
477 #[must_use]
478 #[stable(feature = "futures_api", since = "1.36.0")]
479 pub fn will_wake(&self, other: &Waker) -> bool {
480 // We optimize this by comparing vtable addresses instead of vtable contents.
481 // This is permitted since the function is documented as best-effort.
482 let RawWaker { data: a_data, vtable: a_vtable } = self.waker;
483 let RawWaker { data: b_data, vtable: b_vtable } = other.waker;
484 a_data == b_data && ptr::eq(a_vtable, b_vtable)
485 }
486
487 /// Creates a new `Waker` from the provided `data` pointer and `vtable`.
488 ///
489 /// The `data` pointer can be used to store arbitrary data as required
490 /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
491 /// that is associated with the task.
492 /// The value of this pointer will get passed to all functions that are part
493 /// of the `vtable` as the first parameter.
494 ///
495 /// It is important to consider that the `data` pointer must point to a
496 /// thread safe type such as an `Arc`.
497 ///
498 /// The `vtable` customizes the behavior of a `Waker`. For each operation
499 /// on the `Waker`, the associated function in the `vtable` will be called.
500 ///
501 /// # Safety
502 ///
503 /// The behavior of the returned `Waker` is undefined if the contract defined
504 /// in [`RawWakerVTable`]'s documentation is not upheld.
505 ///
506 /// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the
507 /// cost of a required heap allocation.)
508 ///
509 /// [`Wake`]: ../../alloc/task/trait.Wake.html
510 #[inline]
511 #[must_use]
512 #[stable(feature = "waker_getters", since = "1.83.0")]
513 #[rustc_const_stable(feature = "waker_getters", since = "1.83.0")]
514 pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self {
515 Waker { waker: RawWaker { data, vtable } }
516 }
517
518 /// Creates a new `Waker` from [`RawWaker`].
519 ///
520 /// # Safety
521 ///
522 /// The behavior of the returned `Waker` is undefined if the contract defined
523 /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
524 ///
525 /// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the
526 /// cost of a required heap allocation.)
527 ///
528 /// [`Wake`]: ../../alloc/task/trait.Wake.html
529 #[inline]
530 #[must_use]
531 #[stable(feature = "futures_api", since = "1.36.0")]
532 #[rustc_const_stable(feature = "const_waker", since = "1.82.0")]
533 pub const unsafe fn from_raw(waker: RawWaker) -> Waker {
534 Waker { waker }
535 }
536
537 /// Returns a reference to a `Waker` that does nothing when used.
538 ///
539 // Note! Much of the documentation for this method is duplicated
540 // in the docs for `LocalWaker::noop`.
541 // If you edit it, consider editing the other copy too.
542 //
543 /// This is mostly useful for writing tests that need a [`Context`] to poll
544 /// some futures, but are not expecting those futures to wake the waker or
545 /// do not need to do anything specific if it happens.
546 ///
547 /// More generally, using `Waker::noop()` to poll a future
548 /// means discarding the notification of when the future should be polled again.
549 /// So it should only be used when such a notification will not be needed to make progress.
550 ///
551 /// If an owned `Waker` is needed, `clone()` this one.
552 ///
553 /// # Examples
554 ///
555 /// ```
556 /// use std::future::Future;
557 /// use std::task;
558 ///
559 /// let mut cx = task::Context::from_waker(task::Waker::noop());
560 ///
561 /// let mut future = Box::pin(async { 10 });
562 /// assert_eq!(future.as_mut().poll(&mut cx), task::Poll::Ready(10));
563 /// ```
564 #[inline]
565 #[must_use]
566 #[stable(feature = "noop_waker", since = "1.85.0")]
567 #[rustc_const_stable(feature = "noop_waker", since = "1.85.0")]
568 pub const fn noop() -> &'static Waker {
569 const WAKER: &Waker = &Waker { waker: RawWaker::NOOP };
570 WAKER
571 }
572
573 /// Gets the `data` pointer used to create this `Waker`.
574 #[inline]
575 #[must_use]
576 #[stable(feature = "waker_getters", since = "1.83.0")]
577 pub fn data(&self) -> *const () {
578 self.waker.data
579 }
580
581 /// Gets the `vtable` pointer used to create this `Waker`.
582 #[inline]
583 #[must_use]
584 #[stable(feature = "waker_getters", since = "1.83.0")]
585 pub fn vtable(&self) -> &'static RawWakerVTable {
586 self.waker.vtable
587 }
588
589 /// Constructs a `Waker` from a function pointer.
590 #[inline]
591 #[must_use]
592 #[unstable(feature = "waker_from_fn_ptr", issue = "148457")]
593 pub const fn from_fn_ptr(f: fn()) -> Self {
594 // SAFETY: Unsafe is used for transmutes, pointer came from `fn()` so it
595 // is sound to transmute it back to `fn()`.
596 static VTABLE: RawWakerVTable = unsafe {
597 RawWakerVTable::new(
598 |this| RawWaker::new(this, &VTABLE),
599 |this| transmute::<*const (), fn()>(this)(),
600 |this| transmute::<*const (), fn()>(this)(),
601 |_| {},
602 )
603 };
604 let raw = RawWaker::new(f as *const (), &VTABLE);
605
606 // SAFETY: `clone` is just a copy, `drop` is a no-op while `wake` and
607 // `wake_by_ref` just call the function pointer.
608 unsafe { Self::from_raw(raw) }
609 }
610}
611
612#[stable(feature = "futures_api", since = "1.36.0")]
613impl Clone for Waker {
614 #[inline]
615 fn clone(&self) -> Self {
616 Waker {
617 // SAFETY: This is safe because `Waker::from_raw` is the only way
618 // to initialize `clone` and `data` requiring the user to acknowledge
619 // that the contract of [`RawWaker`] is upheld.
620 waker: unsafe { (self.waker.vtable.clone)(self.waker.data) },
621 }
622 }
623
624 /// Assigns a clone of `source` to `self`, unless [`self.will_wake(source)`][Waker::will_wake] anyway.
625 ///
626 /// This method is preferred over simply assigning `source.clone()` to `self`,
627 /// as it avoids cloning the waker if `self` is already the same waker.
628 ///
629 /// # Examples
630 ///
631 /// ```
632 /// use std::future::Future;
633 /// use std::pin::Pin;
634 /// use std::sync::{Arc, Mutex};
635 /// use std::task::{Context, Poll, Waker};
636 ///
637 /// struct Waiter {
638 /// shared: Arc<Mutex<Shared>>,
639 /// }
640 ///
641 /// struct Shared {
642 /// waker: Waker,
643 /// // ...
644 /// }
645 ///
646 /// impl Future for Waiter {
647 /// type Output = ();
648 /// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
649 /// let mut shared = self.shared.lock().unwrap();
650 ///
651 /// // update the waker
652 /// shared.waker.clone_from(cx.waker());
653 ///
654 /// // readiness logic ...
655 /// # Poll::Ready(())
656 /// }
657 /// }
658 ///
659 /// ```
660 #[inline]
661 fn clone_from(&mut self, source: &Self) {
662 if !self.will_wake(source) {
663 *self = source.clone();
664 }
665 }
666}
667
668#[stable(feature = "futures_api", since = "1.36.0")]
669impl Drop for Waker {
670 #[inline]
671 fn drop(&mut self) {
672 // SAFETY: This is safe because `Waker::from_raw` is the only way
673 // to initialize `drop` and `data` requiring the user to acknowledge
674 // that the contract of `RawWaker` is upheld.
675 unsafe { (self.waker.vtable.drop)(self.waker.data) }
676 }
677}
678
679#[stable(feature = "futures_api", since = "1.36.0")]
680impl fmt::Debug for Waker {
681 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
682 let vtable_ptr = self.waker.vtable as *const RawWakerVTable;
683 f.debug_struct("Waker")
684 .field("data", &self.waker.data)
685 .field("vtable", &vtable_ptr)
686 .finish()
687 }
688}
689
690/// A `LocalWaker` is analogous to a [`Waker`], but it does not implement [`Send`] or [`Sync`].
691///
692/// This handle encapsulates a [`RawWaker`] instance, which defines the
693/// executor-specific wakeup behavior.
694///
695/// Local wakers can be requested from a `Context` with the [`local_waker`] method.
696///
697/// The typical life of a `LocalWaker` is that it is constructed by an executor, wrapped in a
698/// [`Context`] using [`ContextBuilder`], then passed to [`Future::poll()`]. Then, if the future chooses to return
699/// [`Poll::Pending`], it must also store the waker somehow and call [`LocalWaker::wake()`] when
700/// the future should be polled again.
701///
702/// Implements [`Clone`], but neither [`Send`] nor [`Sync`]; therefore, a local waker may
703/// not be moved to other threads. In general, when deciding to use wakers or local wakers,
704/// local wakers are preferable unless the waker needs to be sent across threads. This is because
705/// wakers can incur in additional cost related to memory synchronization.
706///
707/// Note that it is preferable to use `local_waker.clone_from(&new_waker)` instead
708/// of `*local_waker = new_waker.clone()`, as the former will avoid cloning the waker
709/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
710///
711/// # Examples
712/// Usage of a local waker to implement a future analogous to `std::thread::yield_now()`.
713/// ```
714/// #![feature(local_waker)]
715/// use std::future::{Future, poll_fn};
716/// use std::task::Poll;
717///
718/// // a future that returns pending once.
719/// fn yield_now() -> impl Future<Output=()> + Unpin {
720/// let mut yielded = false;
721/// poll_fn(move |cx| {
722/// if !yielded {
723/// yielded = true;
724/// cx.local_waker().wake_by_ref();
725/// return Poll::Pending;
726/// }
727/// return Poll::Ready(())
728/// })
729/// }
730///
731/// # async fn __() {
732/// yield_now().await;
733/// # }
734/// ```
735///
736/// [`Future::poll()`]: core::future::Future::poll
737/// [`Poll::Pending`]: core::task::Poll::Pending
738/// [`local_waker`]: core::task::Context::local_waker
739#[unstable(feature = "local_waker", issue = "118959")]
740#[repr(transparent)]
741pub struct LocalWaker {
742 waker: RawWaker,
743}
744
745#[unstable(feature = "local_waker", issue = "118959")]
746impl Unpin for LocalWaker {}
747
748impl LocalWaker {
749 /// Wakes up the task associated with this `LocalWaker`.
750 ///
751 /// As long as the executor keeps running and the task is not finished, it is
752 /// guaranteed that each invocation of [`wake()`](Self::wake) (or
753 /// [`wake_by_ref()`](Self::wake_by_ref)) will be followed by at least one
754 /// [`poll()`] of the task to which this `LocalWaker` belongs. This makes
755 /// it possible to temporarily yield to other tasks while running potentially
756 /// unbounded processing loops.
757 ///
758 /// Note that the above implies that multiple wake-ups may be coalesced into a
759 /// single [`poll()`] invocation by the runtime.
760 ///
761 /// Also note that yielding to competing tasks is not guaranteed: it is the
762 /// executor’s choice which task to run and the executor may choose to run the
763 /// current task again.
764 ///
765 /// [`poll()`]: crate::future::Future::poll
766 #[inline]
767 #[unstable(feature = "local_waker", issue = "118959")]
768 pub fn wake(self) {
769 // The actual wakeup call is delegated through a virtual function call
770 // to the implementation which is defined by the executor.
771
772 // Don't call `drop` -- the waker will be consumed by `wake`.
773 let this = ManuallyDrop::new(self);
774
775 // SAFETY: This is safe because `Waker::from_raw` is the only way
776 // to initialize `wake` and `data` requiring the user to acknowledge
777 // that the contract of `RawWaker` is upheld.
778 unsafe { (this.waker.vtable.wake)(this.waker.data) };
779 }
780
781 /// Wakes up the task associated with this `LocalWaker` without consuming the `LocalWaker`.
782 ///
783 /// This is similar to [`wake()`](Self::wake), but may be slightly less efficient in
784 /// the case where an owned `Waker` is available. This method should be preferred to
785 /// calling `waker.clone().wake()`.
786 #[inline]
787 #[unstable(feature = "local_waker", issue = "118959")]
788 pub fn wake_by_ref(&self) {
789 // The actual wakeup call is delegated through a virtual function call
790 // to the implementation which is defined by the executor.
791
792 // SAFETY: see `wake`
793 unsafe { (self.waker.vtable.wake_by_ref)(self.waker.data) }
794 }
795
796 /// Returns `true` if this `LocalWaker` and another `LocalWaker` would awake the same task.
797 ///
798 /// This function works on a best-effort basis, and may return false even
799 /// when the `Waker`s would awaken the same task. However, if this function
800 /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
801 ///
802 /// This function is primarily used for optimization purposes — for example,
803 /// this type's [`clone_from`](Self::clone_from) implementation uses it to
804 /// avoid cloning the waker when they would wake the same task anyway.
805 #[inline]
806 #[must_use]
807 #[unstable(feature = "local_waker", issue = "118959")]
808 pub fn will_wake(&self, other: &LocalWaker) -> bool {
809 // We optimize this by comparing vtable addresses instead of vtable contents.
810 // This is permitted since the function is documented as best-effort.
811 let RawWaker { data: a_data, vtable: a_vtable } = self.waker;
812 let RawWaker { data: b_data, vtable: b_vtable } = other.waker;
813 a_data == b_data && ptr::eq(a_vtable, b_vtable)
814 }
815
816 /// Creates a new `LocalWaker` from the provided `data` pointer and `vtable`.
817 ///
818 /// The `data` pointer can be used to store arbitrary data as required
819 /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
820 /// that is associated with the task.
821 /// The value of this pointer will get passed to all functions that are part
822 /// of the `vtable` as the first parameter.
823 ///
824 /// The `vtable` customizes the behavior of a `LocalWaker`. For each
825 /// operation on the `LocalWaker`, the associated function in the `vtable`
826 /// will be called.
827 ///
828 /// # Safety
829 ///
830 /// The behavior of the returned `Waker` is undefined if the contract defined
831 /// in [`RawWakerVTable`]'s documentation is not upheld.
832 ///
833 #[inline]
834 #[must_use]
835 #[unstable(feature = "local_waker", issue = "118959")]
836 pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self {
837 LocalWaker { waker: RawWaker { data, vtable } }
838 }
839
840 /// Creates a new `LocalWaker` from [`RawWaker`].
841 ///
842 /// The behavior of the returned `LocalWaker` is undefined if the contract defined
843 /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
844 /// Therefore this method is unsafe.
845 #[inline]
846 #[must_use]
847 #[unstable(feature = "local_waker", issue = "118959")]
848 pub const unsafe fn from_raw(waker: RawWaker) -> LocalWaker {
849 Self { waker }
850 }
851
852 /// Returns a reference to a `LocalWaker` that does nothing when used.
853 ///
854 // Note! Much of the documentation for this method is duplicated
855 // in the docs for `Waker::noop`.
856 // If you edit it, consider editing the other copy too.
857 //
858 /// This is mostly useful for writing tests that need a [`Context`] to poll
859 /// some futures, but are not expecting those futures to wake the waker or
860 /// do not need to do anything specific if it happens.
861 ///
862 /// More generally, using `LocalWaker::noop()` to poll a future
863 /// means discarding the notification of when the future should be polled again,
864 /// So it should only be used when such a notification will not be needed to make progress.
865 ///
866 /// If an owned `LocalWaker` is needed, `clone()` this one.
867 ///
868 /// # Examples
869 ///
870 /// ```
871 /// #![feature(local_waker)]
872 /// use std::future::Future;
873 /// use std::task::{ContextBuilder, LocalWaker, Waker, Poll};
874 ///
875 /// let mut cx = ContextBuilder::from_waker(Waker::noop())
876 /// .local_waker(LocalWaker::noop())
877 /// .build();
878 ///
879 /// let mut future = Box::pin(async { 10 });
880 /// assert_eq!(future.as_mut().poll(&mut cx), Poll::Ready(10));
881 /// ```
882 #[inline]
883 #[must_use]
884 #[unstable(feature = "local_waker", issue = "118959")]
885 pub const fn noop() -> &'static LocalWaker {
886 const WAKER: &LocalWaker = &LocalWaker { waker: RawWaker::NOOP };
887 WAKER
888 }
889
890 /// Gets the `data` pointer used to create this `LocalWaker`.
891 #[inline]
892 #[must_use]
893 #[unstable(feature = "local_waker", issue = "118959")]
894 pub fn data(&self) -> *const () {
895 self.waker.data
896 }
897
898 /// Gets the `vtable` pointer used to create this `LocalWaker`.
899 #[inline]
900 #[must_use]
901 #[unstable(feature = "local_waker", issue = "118959")]
902 pub fn vtable(&self) -> &'static RawWakerVTable {
903 self.waker.vtable
904 }
905
906 /// Constructs a `LocalWaker` from a function pointer.
907 #[inline]
908 #[must_use]
909 #[unstable(feature = "waker_from_fn_ptr", issue = "148457")]
910 pub const fn from_fn_ptr(f: fn()) -> Self {
911 // SAFETY: Unsafe is used for transmutes, pointer came from `fn()` so it
912 // is sound to transmute it back to `fn()`.
913 static VTABLE: RawWakerVTable = unsafe {
914 RawWakerVTable::new(
915 |this| RawWaker::new(this, &VTABLE),
916 |this| transmute::<*const (), fn()>(this)(),
917 |this| transmute::<*const (), fn()>(this)(),
918 |_| {},
919 )
920 };
921 let raw = RawWaker::new(f as *const (), &VTABLE);
922
923 // SAFETY: `clone` is just a copy, `drop` is a no-op while `wake` and
924 // `wake_by_ref` just call the function pointer.
925 unsafe { Self::from_raw(raw) }
926 }
927}
928#[unstable(feature = "local_waker", issue = "118959")]
929impl Clone for LocalWaker {
930 #[inline]
931 fn clone(&self) -> Self {
932 LocalWaker {
933 // SAFETY: This is safe because `Waker::from_raw` is the only way
934 // to initialize `clone` and `data` requiring the user to acknowledge
935 // that the contract of [`RawWaker`] is upheld.
936 waker: unsafe { (self.waker.vtable.clone)(self.waker.data) },
937 }
938 }
939
940 #[inline]
941 fn clone_from(&mut self, source: &Self) {
942 if !self.will_wake(source) {
943 *self = source.clone();
944 }
945 }
946}
947
948#[unstable(feature = "local_waker", issue = "118959")]
949#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
950const impl AsRef<LocalWaker> for Waker {
951 fn as_ref(&self) -> &LocalWaker {
952 // SAFETY: LocalWaker is just Waker without thread safety
953 unsafe { transmute(self) }
954 }
955}
956
957#[unstable(feature = "local_waker", issue = "118959")]
958impl Drop for LocalWaker {
959 #[inline]
960 fn drop(&mut self) {
961 // SAFETY: This is safe because `LocalWaker::from_raw` is the only way
962 // to initialize `drop` and `data` requiring the user to acknowledge
963 // that the contract of `RawWaker` is upheld.
964 unsafe { (self.waker.vtable.drop)(self.waker.data) }
965 }
966}
967
968#[unstable(feature = "local_waker", issue = "118959")]
969impl fmt::Debug for LocalWaker {
970 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
971 let vtable_ptr = self.waker.vtable as *const RawWakerVTable;
972 f.debug_struct("LocalWaker")
973 .field("data", &self.waker.data)
974 .field("vtable", &vtable_ptr)
975 .finish()
976 }
977}
978
979#[unstable(feature = "local_waker", issue = "118959")]
980impl !Send for LocalWaker {}
981#[unstable(feature = "local_waker", issue = "118959")]
982impl !Sync for LocalWaker {}