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();