Consider the following code
extern crate futures; // v0.1 (old)
use std::sync::{atomic, Arc};
use futures::*;
struct F(Arc<atomic::AtomicBool>);
impl Future for F {
type Item = ();
type Error = ();
fn poll(&mut self) -> Result<Async<Self::Item>, Self::Error> {
println!("Check if flag is set");
if self.0.load(atomic::Ordering::Relaxed) {
Ok(Async::Ready(()))
} else {
Ok(Async::NotReady)
}
}
}
fn main() {
let flag = Arc::new(atomic::AtomicBool::new(false));
let future = F(flag.clone());
::std::thread::spawn(move || {
::std::thread::sleep_ms(10);
println!("set flag");
flag.store(true, atomic::Ordering::Relaxed);
});
// ::std::thread::sleep_ms(20);
let result = future.wait();
println!("result: {:?}", result);
}
The spawned thread sets a flag, which the future waits for.
We also sleep the spawned thread, so the initial .poll()
call from .wait()
is before the flag is set. This causes .wait()
to block (seemingly) indefinitely. If we uncomment the other thread::sleep_ms
, .wait()
returns, and prints out the result (()
).
I would expect the current thread to try to resolve the future by calling poll
multiple times, since we're blocking the current thread. However, this is not happening.
I have tried to read some docs, and it seems like the problem is that the thread is park
ed after getting NotReady
from the poll
the first time. However, it is not clear to me why this is, or how it is possible to work around this.
What am I missing?