From a8a4a9f0fceb33162bfb34160ac8ceb098c65ee3 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Sun, 1 Dec 2019 12:58:01 -0800 Subject: [PATCH] blocking: fix `spawn_blocking` after shutdown (#1875) The task handle needs to be shutdown explicitly and not dropped. Closes #1853 --- tokio/src/runtime/blocking/pool.rs | 3 +++ tokio/tests/rt_common.rs | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/tokio/src/runtime/blocking/pool.rs b/tokio/src/runtime/blocking/pool.rs index 052d361ad..3e7d401bf 100644 --- a/tokio/src/runtime/blocking/pool.rs +++ b/tokio/src/runtime/blocking/pool.rs @@ -197,6 +197,9 @@ impl Spawner { let mut shared = self.inner.shared.lock().unwrap(); if shared.shutdown { + // Shutdown the task + task.shutdown(); + // no need to even push this task; it would never get picked up return; } diff --git a/tokio/tests/rt_common.rs b/tokio/tests/rt_common.rs index a3b68f1c7..06c966bfe 100644 --- a/tokio/tests/rt_common.rs +++ b/tokio/tests/rt_common.rs @@ -44,7 +44,7 @@ rt_test! { use tokio::prelude::*; use tokio::runtime::Runtime; use tokio::sync::oneshot; - use tokio::time; + use tokio::{task, time}; use tokio_test::{assert_err, assert_ok}; use futures::future::poll_fn; @@ -438,6 +438,23 @@ rt_test! { }); } + #[test] + fn spawn_blocking_after_shutdown() { + let rt = rt(); + let handle = rt.handle().clone(); + + // Shutdown + drop(rt); + + handle.enter(|| { + let res = task::spawn_blocking(|| unreachable!()); + + // Avoid using a tokio runtime + let out = futures::executor::block_on(res); + assert!(out.is_err()); + }); + } + #[test] fn io_driver_called_when_under_load() { let mut rt = rt();