Closed
Description
When calling task::block_on
recursively, the executor seems to dead-lock even when the recursion depth is much smaller than num cpus.
Sample code (deadlocks on a 8-cpu machine):
#[async_std::test]
async fn test_async_deadlock() {
use std::future::Future;
use futures::FutureExt;
fn nth(n: usize) -> impl Future<Output=usize> + Send {
async move {
async_std::task::block_on(async move {
if n == 0 {
0
} else {
let fut = async_std::task::spawn(nth(n-1)).boxed();
fut.await + 1
}
})
}
}
let input = 2;
assert_eq!(nth(input).await, input);
}
It seems that the test should deadlock when input >= num_cpus, but even when input=2, on a 8-cpu machine this seems to deadlock. Is this expected behaviour? Interestingly, input = 1 (which does involve a recursive call) does not deadlock. If the block_on
is removed, the test indeed passes for large input values.
Aside: it would be great if the executor could detect block_on
called within the pool processor threads, and spawn more threads. The block_on
could be considered an explicit hint that the particular worker is probably going to block.