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