mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-09 00:00:08 +02:00
rt: fix spawn_blocking from spawn_blocking (#2006)
Nested spawn_blocking calls would result in a panic due to the necessary context not being setup. This patch sets the blocking pool context from within a blocking pool. Fixes #1982
This commit is contained in:
@@ -244,32 +244,31 @@ impl Spawner {
|
|||||||
builder = builder.stack_size(stack_size);
|
builder = builder.stack_size(stack_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
let inner = self.inner.clone();
|
let spawner = self.clone();
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
inner.run();
|
run_thread(spawner);
|
||||||
|
|
||||||
// Make sure `inner` drops first to ensure that the shutdown_rx
|
|
||||||
// sees all refs to `Inner` are dropped when the `shutdown_rx`
|
|
||||||
// resolves.
|
|
||||||
drop(inner);
|
|
||||||
drop(shutdown_tx);
|
drop(shutdown_tx);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_thread(spawner: Spawner) {
|
||||||
|
spawner.enter(|| {
|
||||||
|
let inner = &*spawner.inner;
|
||||||
|
let _io = io::set_default(&inner.io_handle);
|
||||||
|
|
||||||
|
time::with_default(&inner.time_handle, &inner.clock, || {
|
||||||
|
inner.spawner.enter(|| inner.run());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
impl Inner {
|
impl Inner {
|
||||||
fn run(&self) {
|
fn run(&self) {
|
||||||
let _io = io::set_default(&self.io_handle);
|
|
||||||
|
|
||||||
time::with_default(&self.time_handle, &self.clock, || {
|
|
||||||
self.spawner.enter(|| self.run2());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run2(&self) {
|
|
||||||
if let Some(f) = &self.after_start {
|
if let Some(f) = &self.after_start {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -396,6 +396,21 @@ rt_test! {
|
|||||||
assert_eq!(out, "hello")
|
assert_eq!(out, "hello")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spawn_blocking_from_blocking() {
|
||||||
|
let mut rt = rt();
|
||||||
|
|
||||||
|
let out = rt.block_on(async move {
|
||||||
|
let inner = assert_ok!(tokio::task::spawn_blocking(|| {
|
||||||
|
tokio::task::spawn_blocking(|| "hello")
|
||||||
|
}).await);
|
||||||
|
|
||||||
|
assert_ok!(inner.await)
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(out, "hello")
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn delay_from_blocking() {
|
fn delay_from_blocking() {
|
||||||
let mut rt = rt();
|
let mut rt = rt();
|
||||||
|
|||||||
Reference in New Issue
Block a user