core/task/
wake.rs

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