What is the asynchronous version of yield_now?

#1

For some reason, I need code like this:

async move {
    loop {
        if is_ready() {
            do_something();
            return;
        } else {
            await!( yield_now() ); 
        }
    }
}

In other words, the asynchronous version of std::thread::yield_now()

#2

I think i got it.

pub fn yield_now() -> impl Future<Output=()> {
    YieldNow(false)
}

#[derive(Default)]
struct YieldNow(bool);

impl Future for YieldNow {
    type Output = ();

    fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
        if self.0 {
            Poll::Ready(())
        } else {
            self.0 = true;
            lw.wake();
            Poll::Pending
        }
    }
}

#3

Here is my test code:

#![feature(await_macro, async_await, futures_api)]

use core::task::LocalWaker;
use std::pin::Pin;

use futures::Future;
use futures::future::FutureObj;
use futures::Poll;
use tokio::runtime::current_thread::Runtime; // One task one time

fn main() {
    let mut rt = Runtime::new().unwrap();
    for i in 0..10 {
        rt.spawn(futures::compat::Compat::new(task(i)));
    }
    rt.run().unwrap();
}

fn task(id: usize) -> FutureObj<'static, Result<(), ()>> {
    FutureObj::new(Box::new(
        async move {
            loop {
                println!("task {}", id);
                await!(yield_now());
            }
        },
    ))
}

Output:

task 0
task 1
task 2
task 3
task 4
task 5
task 6
task 7
task 8
task 9

Without await!( yield_now() );, output is:

task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0
task 0