yield_now/
lib.rs

1#![cfg_attr(
2    not(any(feature = "tokio", feature = "async-stds", feature = "futures-lite")),
3    no_std
4)]
5//! Wakes current task and returns [`Poll::Pending`] once
6//!
7//! This function can be used when we want to give
8//! task scheduler time to pause before doing some
9//! long running task.
10//!
11//! # Examples
12//! ```
13//! use yield_now::yield_now;
14//!
15//! # spin_on::spin_on(async {
16//! yield_now().await;
17//! # });
18//! ```
19use core::task::{Context, Poll};
20
21#[allow(unreachable_code)]
22/// Wakes current task and returns [`Poll::Pending`] once
23///
24/// this function will use runtime yield_now depending on
25/// which feature is enabled
26///
27/// see [`tokio::task::yield_now`] for `tokio`
28///
29/// see [`async_std::task::yield_now`] for `async-std`
30///
31/// see [`futures_lite::future::yield_now`] for `futures-lite`
32pub async fn yield_now() {
33    #[cfg(feature = "tokio")]
34    if tokio::runtime::Handle::try_current().is_ok() {
35        return tokio::task::yield_now().await;
36    }
37
38    #[cfg(feature = "async-std")]
39    return async_std::task::yield_now().await;
40
41    #[cfg(feature = "futures-lite")]
42    return futures_lite::future::yield_now().await;
43
44    YieldNow::Yield.await
45}
46
47#[derive(Clone, Copy, Debug)]
48pub enum YieldNow {
49    Yield,
50    Ready,
51}
52
53impl core::future::Future for YieldNow {
54    type Output = ();
55    fn poll(mut self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
56        match *self {
57            Self::Yield => {
58                *self = Self::Ready;
59                cx.waker().wake_by_ref();
60
61                Poll::Pending
62            }
63            Self::Ready => Poll::Ready(()),
64        }
65    }
66}