diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index c23d8dd1b..9ff0cc4c2 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -125,6 +125,7 @@ use reactor::{Background, Handle}; use std::io; +use tokio_executor::enter; use tokio_threadpool as threadpool; use futures; @@ -210,7 +211,9 @@ where F: Future + Send + 'static, { let mut runtime = Runtime::new().unwrap(); runtime.spawn(future); - runtime.shutdown_on_idle().wait().unwrap(); + enter().expect("nested tokio::run") + .block_on(runtime.shutdown_on_idle()) + .unwrap(); } impl Runtime { diff --git a/tests/runtime.rs b/tests/runtime.rs index ac40a6e06..66d10b951 100644 --- a/tests/runtime.rs +++ b/tests/runtime.rs @@ -390,3 +390,15 @@ mod from_block_on_all { test(|f| { tokio::spawn(f); }) } } + +#[test] +fn run_in_run() { + use std::panic; + + tokio::run(lazy(|| { + panic::catch_unwind(|| { + tokio::run(lazy(|| { Ok::<(), ()>(()) })) + }).unwrap_err(); + Ok::<(), ()>(()) + })); +} diff --git a/tokio-executor/src/enter.rs b/tokio-executor/src/enter.rs index c33cf6492..4d9af8ccf 100644 --- a/tokio-executor/src/enter.rs +++ b/tokio-executor/src/enter.rs @@ -3,6 +3,8 @@ use std::cell::Cell; use std::error::Error; use std::fmt; +use futures::{self, Future}; + thread_local!(static ENTERED: Cell = Cell::new(false)); /// Represents an executor context. @@ -80,6 +82,13 @@ impl Enter { pub fn make_permanent(mut self) { self.permanent = true; } + + /// Blocks the thread on the specified future, returning the value with + /// which that future completes. + pub fn block_on(&mut self, f: F) -> Result { + futures::executor::spawn(f).wait_future() + } + } impl fmt::Debug for Enter {