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()
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
}
}
}
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