summaryrefslogtreecommitdiffstats
path: root/tokio/src/runtime
diff options
context:
space:
mode:
authorDan Burkert <dan@danburkert.com>2020-04-24 06:25:48 -0600
committerGitHub <noreply@github.com>2020-04-24 15:25:48 +0300
commitd8139fef7a555f99adaa37e139787d26e24daba3 (patch)
tree5695a5fc6560ca851d12da04464747d161c55790 /tokio/src/runtime
parent9bcb50660e2d9de26a4373aaf4ab8f324c8ebbe8 (diff)
Add Handle::block_on method (#2437)
Diffstat (limited to 'tokio/src/runtime')
-rw-r--r--tokio/src/runtime/enter.rs14
-rw-r--r--tokio/src/runtime/handle.rs41
-rw-r--r--tokio/src/runtime/mod.rs21
3 files changed, 71 insertions, 5 deletions
diff --git a/tokio/src/runtime/enter.rs b/tokio/src/runtime/enter.rs
index 9b3f2ad8..ad5580cc 100644
--- a/tokio/src/runtime/enter.rs
+++ b/tokio/src/runtime/enter.rs
@@ -138,14 +138,11 @@ cfg_rt_threaded! {
}
}
-cfg_blocking_impl! {
- use crate::park::ParkError;
- use std::time::Duration;
-
+cfg_block_on! {
impl Enter {
/// Blocks the thread on the specified future, returning the value with
/// which that future completes.
- pub(crate) fn block_on<F>(&mut self, mut f: F) -> Result<F::Output, ParkError>
+ pub(crate) fn block_on<F>(&mut self, mut f: F) -> Result<F::Output, crate::park::ParkError>
where
F: std::future::Future,
{
@@ -170,7 +167,14 @@ cfg_blocking_impl! {
park.park()?;
}
}
+ }
+}
+cfg_blocking_impl! {
+ use crate::park::ParkError;
+ use std::time::Duration;
+
+ impl Enter {
/// Blocks the thread on the specified future for **at most** `timeout`
///
/// If the future completes before `timeout`, the result is returned. If
diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs
index db53543e..b232431b 100644
--- a/tokio/src/runtime/handle.rs
+++ b/tokio/src/runtime/handle.rs
@@ -119,6 +119,47 @@ cfg_rt_core! {
{
self.spawner.spawn(future)
}
+
+ /// Run a future to completion on the Tokio runtime from a synchronous
+ /// context.
+ ///
+ /// This runs the given future on the runtime, blocking until it is
+ /// complete, and yielding its resolved result. Any tasks or timers which
+ /// the future spawns internally will be executed on the runtime.
+ ///
+ /// This method should not be called from an asynchronous context.
+ ///
+ /// # Panics
+ ///
+ /// This function panics if the executor is at capacity, if the provided
+ /// future panics, or if called within an asynchronous execution context.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use tokio::runtime::Runtime;
+ /// use std::thread;
+ ///
+ /// // Create the runtime
+ /// let rt = Runtime::new().unwrap();
+ /// let handle = rt.handle().clone();
+ ///
+ /// // Use the runtime from another thread
+ /// let th = thread::spawn(move || {
+ /// // Execute the future, blocking the current thread until completion
+ /// handle.block_on(async {
+ /// println!("hello");
+ /// });
+ /// });
+ ///
+ /// th.join().unwrap();
+ /// ```
+ pub fn block_on<F: Future>(&self, future: F) -> F::Output {
+ self.enter(|| {
+ let mut enter = crate::runtime::enter(true);
+ enter.block_on(future).expect("failed to park thread")
+ })
+ }
}
}
diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs
index 2d34e2b6..293f5c93 100644
--- a/tokio/src/runtime/mod.rs
+++ b/tokio/src/runtime/mod.rs
@@ -402,12 +402,33 @@ impl Runtime {
/// complete, and yielding its resolved result. Any tasks or timers which
/// the future spawns internally will be executed on the runtime.
///
+ /// `&mut` is required as calling `block_on` **may** result in advancing the
+ /// state of the runtime. The details depend on how the runtime is
+ /// configured. [`runtime::Handle::block_on`][handle] provides a version
+ /// that takes `&self`.
+ ///
/// This method should not be called from an asynchronous context.
///
/// # Panics
///
/// This function panics if the executor is at capacity, if the provided
/// future panics, or if called within an asynchronous execution context.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use tokio::runtime::Runtime;
+ ///
+ /// // Create the runtime
+ /// let mut rt = Runtime::new().unwrap();
+ ///
+ /// // Execute the future, blocking the current thread until completion
+ /// rt.block_on(async {
+ /// println!("hello");
+ /// });
+ /// ```
+ ///
+ /// [handle]: fn@Handle::block_on
pub fn block_on<F: Future>(&mut self, future: F) -> F::Output {
let kind = &mut self.kind;