1 | use core::future::Future; |
2 | use core::pin::Pin; |
3 | use core::task::{Context, Poll}; |
4 | |
5 | /// Yield from the current task once, allowing other tasks to run. |
6 | /// |
7 | /// This can be used to easily and quickly implement simple async primitives |
8 | /// without using wakers. The following snippet will wait for a condition to |
9 | /// hold, while still allowing other tasks to run concurrently (not monopolizing |
10 | /// the executor thread). |
11 | /// |
12 | /// ```rust,no_run |
13 | /// while !some_condition() { |
14 | /// yield_now().await; |
15 | /// } |
16 | /// ``` |
17 | /// |
18 | /// The downside is this will spin in a busy loop, using 100% of the CPU, while |
19 | /// using wakers correctly would allow the CPU to sleep while waiting. |
20 | /// |
21 | /// The internal implementation is: on first poll the future wakes itself and |
22 | /// returns `Poll::Pending`. On second poll, it returns `Poll::Ready`. |
23 | pub fn yield_now() -> impl Future<Output = ()> { |
24 | YieldNowFuture { yielded: false } |
25 | } |
26 | |
27 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
28 | struct YieldNowFuture { |
29 | yielded: bool, |
30 | } |
31 | |
32 | impl Future for YieldNowFuture { |
33 | type Output = (); |
34 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
35 | if self.yielded { |
36 | Poll::Ready(()) |
37 | } else { |
38 | self.yielded = true; |
39 | cx.waker().wake_by_ref(); |
40 | Poll::Pending |
41 | } |
42 | } |
43 | } |
44 | |