Guard run_executor
of local_pool.rs
against use of park / unpark in user-code.
#2010
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
If user code that is run as a result of polling the futures in the
run_executor
loop oflocal_pool.rs
makes use of the park / unpark APIs, execution may stall due to wakeups getting "lost". This is prevented in this PR through an additionalAtomicBool
that is in full control of the code inlocal_pool.rs
.This problem appeared in practice in the context of using the functions from
local_pool.rs
in combination withasync_std::net::stream::TcpStream::connect()
, which usesspawn_blocking
which accesses a thread pool behind aonce_cell::sync::Lazy
, which in turn parks/unparks threads on concurrent access to the lazy value while initialisation is ongoing. As a result it sporadically happened that execution would stall as a "token" made available byunpark()
would be "consumed" byonce_cell
and execution stall on the nextpark()
. The included test reconstructs such a scenario.Though not intentional, this change also seems to have a small positive impact on the benchmarks, possibly due to avoiding unnecessary calls to
park
/unpark
:Lastly, a possible alternative may be to use e.g.
crossbeam::sync::Parker
though that would introduce a new dependency.