Skip to content

Commit d6aa1fb

Browse files
yoshuawuytsStjepan Glavina
authored and
Stjepan Glavina
committed
Add task::yield_now as "unstable" (#300)
Signed-off-by: Yoshua Wuyts <[email protected]>
1 parent 454018e commit d6aa1fb

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

src/task/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ mod worker;
4949

5050
pub(crate) mod blocking;
5151

52+
cfg_if::cfg_if! {
53+
if #[cfg(any(feature = "unstable", feature = "docs"))] {
54+
mod yield_now;
55+
pub use yield_now::yield_now;
56+
}
57+
}
58+
5259
/// Spawns a blocking task.
5360
///
5461
/// The task will be spawned onto a thread pool specifically dedicated to blocking tasks. This

src/task/yield_now.rs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use crate::future::Future;
2+
use crate::task::{Context, Poll};
3+
4+
use std::pin::Pin;
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+
/// # fn main() { async_std::task::block_on(async {
22+
/// #
23+
/// use async_std::task;
24+
///
25+
/// task::yield_now().await;
26+
/// #
27+
/// # }) }
28+
/// ```
29+
#[cfg(any(feature = "unstable", feature = "docs"))]
30+
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
31+
#[inline]
32+
pub async fn yield_now() {
33+
YieldNow(false).await
34+
}
35+
36+
struct YieldNow(bool);
37+
38+
impl Future for YieldNow {
39+
type Output = ();
40+
41+
// The futures executor is implemented as a FIFO queue, so all this future
42+
// does is re-schedule the future back to the end of the queue, giving room
43+
// for other futures to progress.
44+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
45+
if !self.0 {
46+
self.0 = true;
47+
cx.waker().wake_by_ref();
48+
Poll::Pending
49+
} else {
50+
Poll::Ready(())
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)