| 1 | use std::future::Future; |
| 2 | use std::pin::Pin; |
| 3 | |
| 4 | use crate::task::{Context, Poll}; |
| 5 | |
| 6 | /// Cooperatively gives up a timeslice to the task scheduler. |
| 7 | /// |
| 8 | /// Calling this function will move the currently executing future to the back |
| 9 | /// of the execution queue, making room for other futures to execute. This is |
| 10 | /// especially useful after running CPU-intensive operations inside a future. |
| 11 | /// |
| 12 | /// See also [`task::spawn_blocking`]. |
| 13 | /// |
| 14 | /// [`task::spawn_blocking`]: fn.spawn_blocking.html |
| 15 | /// |
| 16 | /// # Examples |
| 17 | /// |
| 18 | /// Basic usage: |
| 19 | /// |
| 20 | /// ``` |
| 21 | /// # async_std::task::block_on(async { |
| 22 | /// # |
| 23 | /// use async_std::task; |
| 24 | /// |
| 25 | /// task::yield_now().await; |
| 26 | /// # |
| 27 | /// # }) |
| 28 | /// ``` |
| 29 | #[inline ] |
| 30 | pub async fn yield_now() { |
| 31 | YieldNow(false).await |
| 32 | } |
| 33 | |
| 34 | struct YieldNow(bool); |
| 35 | |
| 36 | impl Future for YieldNow { |
| 37 | type Output = (); |
| 38 | |
| 39 | // The futures executor is implemented as a FIFO queue, so all this future |
| 40 | // does is re-schedule the future back to the end of the queue, giving room |
| 41 | // for other futures to progress. |
| 42 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 43 | if !self.0 { |
| 44 | self.0 = true; |
| 45 | cx.waker().wake_by_ref(); |
| 46 | Poll::Pending |
| 47 | } else { |
| 48 | Poll::Ready(()) |
| 49 | } |
| 50 | } |
| 51 | } |
| 52 | |