diff --git a/tokio/src/runtime/context.rs b/tokio/src/runtime/context.rs index 76918114bc3..12f6edf1321 100644 --- a/tokio/src/runtime/context.rs +++ b/tokio/src/runtime/context.rs @@ -183,7 +183,14 @@ cfg_rt! { #[track_caller] pub(super) fn with_scheduler(f: impl FnOnce(Option<&scheduler::Context>) -> R) -> R { let mut f = Some(f); - CONTEXT.try_with(|c| c.scheduler.with(f.take().unwrap())) + CONTEXT.try_with(|c| { + let f = f.take().unwrap(); + if matches!(c.runtime.get(), EnterRuntime::Entered { .. }) { + c.scheduler.with(f) + } else { + f(None) + } + }) .unwrap_or_else(|_| (f.take().unwrap())(None)) } diff --git a/tokio/tests/task_yield_now.rs b/tokio/tests/task_yield_now.rs index 3cb8cb16e70..9efbebb0518 100644 --- a/tokio/tests/task_yield_now.rs +++ b/tokio/tests/task_yield_now.rs @@ -15,3 +15,11 @@ fn yield_now_outside_of_runtime() { assert!(task.is_woken()); assert!(task.poll().is_ready()); } + +#[tokio::test(flavor = "multi_thread")] +async fn yield_now_external_executor_and_block_in_place() { + let j = tokio::spawn(async { + task::block_in_place(|| futures::executor::block_on(task::yield_now())); + }); + j.await.unwrap(); +}