Futures-rs: Recursive use of block_on panics

Created on 27 Feb 2020  路  7Comments  路  Source: rust-lang/futures-rs

When futures::executor::block_on is called recursively it panics with:

thread 'main' panicked at 'cannot execute `LocalPool` executor from within another executor: EnterError', src/libcore/result.rs:1188:5

Here is a complete program to reproduce this result:

fn main() {
    use futures::executor::block_on;
    block_on(async { block_on( async {} ) })
}

The documentation for block_on does not mention any limitation that would cause a panic, and it is unclear (to me at least) that such a limitation would be necessary.

The actual code that causes this panic is here in local_pool.rs

A-executor S-blocked

Most helpful comment

If block_on purposely panics, it should give a relevent panic message. The current one is phrased in terms of the internals of block_on, which is not informative and implies that the panic is not correct.

All 7 comments

I believe our implementation of block on in async-std handles this case: impl here. Maybe it could make sense for futures-rs to adopt a similar fix?

It purposefully panics because a recursive call means blocking any other futures that were running on the same thread.

Yeah, @seanmonstar is right-- this is "working as intended". It's quite bugprone (or arguably always wrong) to block inside the implementation of a future. I'll leave this issue open for discussion, but I don't personally think there's a bug to be fixed here.

Yes, I'm coming around and think that the panic here is reasonable and desirable.

I was originally thinking that at the very least the docs should be amended to document the potential panic - but the more I think about it "Future.poll must never block" is documented and must be well-known and adhered to across the ecosystem. Violating that constraint could cause anything to happen (undefined behavior excepted) in library code - even panics.

I have a use case where I know that the parent executor is idle and need to interact with some code that isn't async. It would be nice to be able to do this for the weird cases where it is needed. I know that it isn't the "perfect" solution in most cases but when you need it, well, you need it.

If block_on purposely panics, it should give a relevent panic message. The current one is phrased in terms of the internals of block_on, which is not informative and implies that the panic is not correct.

We can allow this once the lint like the one that this shiny future story mentions is implemented.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xrl picture xrl  路  3Comments

jedisct1 picture jedisct1  路  3Comments

Nemo157 picture Nemo157  路  5Comments

mqudsi picture mqudsi  路  5Comments

flying-sheep picture flying-sheep  路  3Comments