core/task/
wake.rs

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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy