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