Skip to content

Commit

Permalink
rt: allow block_on inside block_in_place inside block_on (tokio-rs#2645)
Browse files Browse the repository at this point in the history
A fast path in block_on_place was failing to call exit() in the case where we
were in a block_on call.

Fixes: tokio-rs#2639

Co-authored-by: Bryan Donlan <bdonlan@amazon.com>
  • Loading branch information
bdonlan and Bryan Donlan authored Jul 15, 2020
1 parent b9e3d2e commit fc63fa2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
6 changes: 5 additions & 1 deletion tokio/src/runtime/thread_pool/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,19 @@ cfg_blocking! {
}

let mut had_core = false;
let mut had_entered = false;

CURRENT.with(|maybe_cx| {
match (crate::runtime::enter::context(), maybe_cx.is_some()) {
(EnterContext::Entered { .. }, true) => {
// We are on a thread pool runtime thread, so we just need to set up blocking.
had_entered = true;
}
(EnterContext::Entered { allow_blocking }, false) => {
// We are on an executor, but _not_ on the thread pool.
// That is _only_ okay if we are in a thread pool runtime's block_on method:
if allow_blocking {
had_entered = true;
return;
} else {
// This probably means we are on the basic_scheduler or in a LocalSet,
Expand Down Expand Up @@ -256,12 +259,13 @@ cfg_blocking! {
runtime::spawn_blocking(move || run(worker));
});


if had_core {
// Unset the current task's budget. Blocking sections are not
// constrained by task budgets.
let _reset = Reset(coop::stop());

crate::runtime::enter::exit(f)
} else if had_entered {
crate::runtime::enter::exit(f)
} else {
f()
Expand Down
19 changes: 19 additions & 0 deletions tokio/tests/task_blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,22 @@ fn no_block_in_basic_block_on() {
task::block_in_place(|| {});
});
}

#[test]
fn can_enter_basic_rt_from_within_block_in_place() {
let mut outer = tokio::runtime::Builder::new()
.threaded_scheduler()
.build()
.unwrap();

outer.block_on(async {
tokio::task::block_in_place(|| {
let mut inner = tokio::runtime::Builder::new()
.basic_scheduler()
.build()
.unwrap();

inner.block_on(async {})
})
});
}

0 comments on commit fc63fa2

Please sign in to comment.