@@ -7,7 +7,7 @@ use crate::marker::PhantomData;
7
7
use crate :: ptr;
8
8
9
9
/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
10
- /// which provides customized wakeup behavior.
10
+ /// or a [`LocalWaker`] which provides customized wakeup behavior.
11
11
///
12
12
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
13
13
///
@@ -35,9 +35,18 @@ impl RawWaker {
35
35
/// The value of this pointer will get passed to all functions that are part
36
36
/// of the `vtable` as the first parameter.
37
37
///
38
+ /// It is important to consider that the `data` pointer must point to a
39
+ /// thread safe type such as an `[Arc]<T: Send + Sync>`
40
+ /// when used to construct a [`Waker`]. This restriction is lifted when
41
+ /// constructing a [`LocalWaker`], which allows using types that do not implement
42
+ /// <code>[Send] + [Sync]</code> like `[Rc]<T: !Send + !Sync>`.
43
+ ///
38
44
/// The `vtable` customizes the behavior of a `Waker` which gets created
39
45
/// from a `RawWaker`. For each operation on the `Waker`, the associated
40
46
/// function in the `vtable` of the underlying `RawWaker` will be called.
47
+ ///
48
+ /// [`Arc`]: std::sync::Arc
49
+ /// [`Rc`]: std::rc::Rc
41
50
#[ inline]
42
51
#[ rustc_promotable]
43
52
#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
@@ -90,11 +99,19 @@ impl RawWaker {
90
99
/// [`RawWaker`] implementation. Calling one of the contained functions using
91
100
/// any other `data` pointer will cause undefined behavior.
92
101
///
93
- /// These functions must all be thread-safe (even though [`RawWaker`] is
94
- /// <code>\![Send] + \![Sync]</code>)
95
- /// because [`Waker`] is <code>[Send] + [Sync]</code>, and thus wakers may be moved to
96
- /// arbitrary threads or invoked by `&` reference. For example, this means that if the
97
- /// `clone` and `drop` functions manage a reference count, they must do so atomically.
102
+ /// # Thread safety
103
+ /// If the [`RawWaker`] will be used to construct a [`Waker`] then
104
+ /// these functions must all be thread-safe (even though [`RawWaker`] is
105
+ /// <code>\![Send] + \![Sync]</code>). This is because [`Waker`] is <code>[Send] + [Sync]</code>,
106
+ /// and it may be moved to arbitrary threads or invoked by `&` reference. For example,
107
+ /// this means that if the `clone` and `drop` functions manage a reference count,
108
+ /// they must do so atomically.
109
+ ///
110
+ /// However, if the [`RawWaker`] will be used to construct a [`LocalWaker`] instead, then
111
+ /// these functions don't need to be thread safe. This means that <code>\![Send] + \![Sync]</code>
112
+ /// data can be stored in the data pointer, and reference counting does not need any atomic
113
+ /// synchronization. This is because [`LocalWaker`] is not thread safe itself, so it cannot
114
+ /// be sent across threads.
98
115
#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
99
116
#[ derive( PartialEq , Copy , Clone , Debug ) ]
100
117
pub struct RawWakerVTable {
@@ -134,16 +151,22 @@ impl RawWakerVTable {
134
151
/// Creates a new `RawWakerVTable` from the provided `clone`, `wake`,
135
152
/// `wake_by_ref`, and `drop` functions.
136
153
///
137
- /// These functions must all be thread-safe (even though [`RawWaker`] is
138
- /// <code>\![Send] + \![Sync]</code>)
139
- /// because [`Waker`] is <code>[Send] + [Sync]</code>, and thus wakers may be moved to
140
- /// arbitrary threads or invoked by `&` reference. For example, this means that if the
141
- /// `clone` and `drop` functions manage a reference count, they must do so atomically.
142
- ///
154
+ /// If the [`RawWaker`] will be used to construct a [`Waker`] then
155
+ /// these functions must all be thread-safe (even though [`RawWaker`] is
156
+ /// <code>\![Send] + \![Sync]</code>). This is because [`Waker`] is <code>[Send] + [Sync]</code>,
157
+ /// and it may be moved to arbitrary threads or invoked by `&` reference. For example,
158
+ /// this means that if the `clone` and `drop` functions manage a reference count,
159
+ /// they must do so atomically.
160
+ ///
161
+ /// However, if the [`RawWaker`] will be used to construct a [`LocalWaker`] instead, then
162
+ /// these functions don't need to be thread safe. This means that <code>\![Send] + \![Sync]</code>
163
+ /// data can be stored in the data pointer, and reference counting does not need any atomic
164
+ /// synchronization. This is because [`LocalWaker`] is not thread safe itself, so it cannot
165
+ /// be sent across threads.
143
166
/// # `clone`
144
167
///
145
168
/// This function will be called when the [`RawWaker`] gets cloned, e.g. when
146
- /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned.
169
+ /// the [`Waker`]/[`LocalWaker`] in which the [`RawWaker`] is stored gets cloned.
147
170
///
148
171
/// The implementation of this function must retain all resources that are
149
172
/// required for this additional instance of a [`RawWaker`] and associated
@@ -169,7 +192,7 @@ impl RawWakerVTable {
169
192
///
170
193
/// # `drop`
171
194
///
172
- /// This function gets called when a [`Waker`] gets dropped.
195
+ /// This function gets called when a [`Waker`]/[`LocalWaker`] gets dropped.
173
196
///
174
197
/// The implementation of this function must make sure to release any
175
198
/// resources that are associated with this instance of a [`RawWaker`] and
@@ -335,13 +358,13 @@ impl<'a> ContextBuilder<'a> {
335
358
}
336
359
}
337
360
338
- /// Construct a `ContextBuilder`` from a `Context`. This is useful for
361
+ /// Construct a [ `ContextBuilder`] from a [ `Context`] . This is useful for
339
362
/// overriding values from a context.
340
363
///
341
364
/// # Examples
342
- /// An example of a future that allows to set a Waker on Context if none was defined.
343
- /// This can be used to await futures that require a `Waker` even if the runtime does not
344
- /// support `Waker`.
365
+ /// An example of a future that allows to set a [` Waker`] on Context if none was defined.
366
+ /// This can be used to await futures that require a [ `Waker`] even if the runtime does not
367
+ /// support [ `Waker`] .
345
368
/// ```rust
346
369
/// #![feature(noop_waker, local_waker)]
347
370
/// use std::task::{Waker, ContextBuilder};
@@ -596,7 +619,7 @@ impl fmt::Debug for Waker {
596
619
/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
597
620
///
598
621
/// # Examples
599
- /// Usage of a local waker to implement a future
622
+ /// Usage of a local waker to implement a future analogous to `std::thread::yield_now()`.
600
623
/// ```
601
624
/// #![feature(local_waker)]
602
625
/// use std::future::{Future, poll_fn};
@@ -623,6 +646,7 @@ impl fmt::Debug for Waker {
623
646
/// [`Future::poll()`]: core::future::Future::poll
624
647
/// [`Poll::Pending`]: core::task::Poll::Pending
625
648
/// [`local_waker`]: core::task::Context::local_waker
649
+
626
650
#[ unstable( feature = "local_waker" , issue = "118959" ) ]
627
651
#[ repr( transparent) ]
628
652
pub struct LocalWaker {
0 commit comments