schets / multiqueue

A fast mpmc queue with broadcast capabilities
MIT License
201 stars 29 forks source link

Futures polling can block #30

Open idletea opened 5 years ago

idletea commented 5 years ago

An example test which will fail (or more accurately: block infinitely)

#[test]
fn futures_do_not_block() {
    let (tx, rx) = multiqueue::broadcast_fut_queue::<i32>(16);
    let mut rt = tokio::runtime::Runtime::new().unwrap();
    rt.block_on(
        rx
        .for_each(|_| {
            futures::future::ok(())
        })
        .into_future()
        .timeout(Duration::from_millis(100))
        .then(|result| {
            match result {
                Ok(_) => Err("this never has a change to even come up - the above blocks forever"),
                Err(_) => Ok("timed out as expected"),
            }
        })
    ).unwrap();
}

This test will hang because this loop has a case in which it'll keep spinning on the recv attempt and never returns control to the event loop.

As such the timeout never has a chance to be considered reached and the future never resolves even with the timeout on it.