| 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 | |