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