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