1 | #![stable (feature = "futures_api" , since = "1.36.0" )] |
2 | |
3 | use crate::mem::transmute; |
4 | |
5 | use crate::any::Any; |
6 | use crate::fmt; |
7 | use crate::marker::PhantomData; |
8 | use 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" )] |
23 | pub 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 | |
34 | impl 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)] |
128 | pub 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 | |
161 | impl 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)] |
225 | enum 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" ] |
236 | pub 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 | |
250 | impl<'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" )] |
290 | impl 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)] |
320 | pub 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 | |
334 | impl<'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" )] |
431 | pub struct Waker { |
432 | waker: RawWaker, |
433 | } |
434 | |
435 | #[stable (feature = "futures_api" , since = "1.36.0" )] |
436 | impl Unpin for Waker {} |
437 | #[stable (feature = "futures_api" , since = "1.36.0" )] |
438 | unsafe impl Send for Waker {} |
439 | #[stable (feature = "futures_api" , since = "1.36.0" )] |
440 | unsafe impl Sync for Waker {} |
441 | |
442 | impl 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" )] |
568 | impl 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" )] |
624 | impl 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" )] |
635 | impl 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 |
696 | pub struct LocalWaker { |
697 | waker: RawWaker, |
698 | } |
699 | |
700 | #[unstable (feature = "local_waker" , issue = "118959" )] |
701 | impl Unpin for LocalWaker {} |
702 | |
703 | impl 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" )] |
821 | impl 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" )] |
841 | impl 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" )] |
849 | impl 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" )] |
860 | impl 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" )] |
871 | impl !Send for LocalWaker {} |
872 | #[unstable (feature = "local_waker" , issue = "118959" )] |
873 | impl !Sync for LocalWaker {} |
874 | |