diff options
author | Carl Lerche <me@carllerche.com> | 2019-11-16 23:35:04 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-16 23:35:04 -0800 |
commit | b1d9e55487d8411da89788ce0fbb3eb99a1f3a40 (patch) | |
tree | 4561bcaec9e2b011e6741c7fdc84fdefa1716deb /tokio | |
parent | 66cbed3ce302e43f18c7d0a6673886404570fb39 (diff) |
task: move blocking fns into `tokio::task` (#1781)
Diffstat (limited to 'tokio')
-rw-r--r-- | tokio/src/blocking/mod.rs | 60 | ||||
-rw-r--r-- | tokio/src/blocking/pool.rs | 2 | ||||
-rw-r--r-- | tokio/src/lib.rs | 2 | ||||
-rw-r--r-- | tokio/src/runtime/thread_pool/tests/loom_pool.rs | 4 | ||||
-rw-r--r-- | tokio/src/task/blocking.rs | 62 | ||||
-rw-r--r-- | tokio/src/task/mod.rs | 7 | ||||
-rw-r--r-- | tokio/tests/rt_threaded.rs | 2 |
7 files changed, 75 insertions, 64 deletions
diff --git a/tokio/src/blocking/mod.rs b/tokio/src/blocking/mod.rs index 1a2b4d11..ae830b49 100644 --- a/tokio/src/blocking/mod.rs +++ b/tokio/src/blocking/mod.rs @@ -1,65 +1,7 @@ //! Perform blocking operations from an asynchronous context. mod pool; -pub(crate) use self::pool::{BlockingPool, Spawner}; +pub(crate) use self::pool::{spawn_blocking, BlockingPool, Spawner}; mod schedule; mod task; - -use crate::task::JoinHandle; - -/// Run the provided blocking function without blocking the executor. -/// -/// In general, issuing a blocking call or performing a lot of compute in a -/// future without yielding is not okay, as it may prevent the executor from -/// driving other futures forward. If you run a closure through this method, -/// the current executor thread will relegate all its executor duties to another -/// (possibly new) thread, and only then poll the task. Note that this requires -/// additional synchronization. -/// -/// # Examples -/// -/// ``` -/// # async fn docs() { -/// tokio::blocking::in_place(move || { -/// // do some compute-heavy work or call synchronous code -/// }); -/// # } -/// ``` -#[cfg(feature = "rt-full")] -pub fn in_place<F, R>(f: F) -> R -where - F: FnOnce() -> R, -{ - use crate::runtime::{enter, thread_pool}; - - enter::exit(|| thread_pool::block_in_place(f)) -} - -/// Run the provided closure on a thread where blocking is acceptable. -/// -/// In general, issuing a blocking call or performing a lot of compute in a future without -/// yielding is not okay, as it may prevent the executor from driving other futures forward. -/// A closure that is run through this method will instead be run on a dedicated thread pool for -/// such blocking tasks without holding up the main futures executor. -/// -/// # Examples -/// -/// ``` -/// # async fn docs() -> Result<(), Box<dyn std::error::Error>>{ -/// let res = tokio::blocking::spawn_blocking(move || { -/// // do some compute-heavy work or call synchronous code -/// "done computing" -/// }).await?; -/// -/// assert_eq!(res, "done computing"); -/// # Ok(()) -/// # } -/// ``` -pub fn spawn_blocking<F, R>(f: F) -> JoinHandle<R> -where - F: FnOnce() -> R + Send + 'static, - R: Send + 'static, -{ - pool::spawn(f) -} diff --git a/tokio/src/blocking/pool.rs b/tokio/src/blocking/pool.rs index 45161107..fccfc18e 100644 --- a/tokio/src/blocking/pool.rs +++ b/tokio/src/blocking/pool.rs @@ -53,7 +53,7 @@ const MAX_THREADS: u32 = 1_000; const KEEP_ALIVE: Duration = Duration::from_secs(10); /// Run the provided function on an executor dedicated to blocking operations. -pub(super) fn spawn<F, R>(func: F) -> JoinHandle<R> +pub(crate) fn spawn_blocking<F, R>(func: F) -> JoinHandle<R> where F: FnOnce() -> R + Send + 'static, { diff --git a/tokio/src/lib.rs b/tokio/src/lib.rs index cfb90549..81d93c68 100644 --- a/tokio/src/lib.rs +++ b/tokio/src/lib.rs @@ -90,7 +90,7 @@ macro_rules! ready { mod tests; #[cfg(feature = "blocking")] -pub mod blocking; +pub(crate) mod blocking; #[cfg(feature = "fs")] pub mod fs; diff --git a/tokio/src/runtime/thread_pool/tests/loom_pool.rs b/tokio/src/runtime/thread_pool/tests/loom_pool.rs index 7b8becf2..b982e24e 100644 --- a/tokio/src/runtime/thread_pool/tests/loom_pool.rs +++ b/tokio/src/runtime/thread_pool/tests/loom_pool.rs @@ -50,7 +50,7 @@ fn only_blocking() { let (block_tx, block_rx) = oneshot::channel(); pool.spawn(async move { - crate::blocking::in_place(move || { + crate::task::block_in_place(move || { block_tx.send(()); }) }); @@ -72,7 +72,7 @@ fn blocking_and_regular() { let done_tx = Arc::new(Mutex::new(Some(done_tx))); pool.spawn(async move { - crate::blocking::in_place(move || { + crate::task::block_in_place(move || { block_tx.send(()); }) }); diff --git a/tokio/src/task/blocking.rs b/tokio/src/task/blocking.rs new file mode 100644 index 00000000..e0c12d4a --- /dev/null +++ b/tokio/src/task/blocking.rs @@ -0,0 +1,62 @@ +use crate::blocking; +use crate::task::JoinHandle; + +/// Run the provided blocking function without blocking the executor. +/// +/// In general, issuing a blocking call or performing a lot of compute in a +/// future without yielding is not okay, as it may prevent the executor from +/// driving other futures forward. If you run a closure through this method, +/// the current executor thread will relegate all its executor duties to another +/// (possibly new) thread, and only then poll the task. Note that this requires +/// additional synchronization. +/// +/// # Examples +/// +/// ``` +/// use tokio::task; +/// +/// # async fn docs() { +/// task::block_in_place(move || { +/// // do some compute-heavy work or call synchronous code +/// }); +/// # } +/// ``` +#[cfg(feature = "rt-full")] +pub fn block_in_place<F, R>(f: F) -> R +where + F: FnOnce() -> R, +{ + use crate::runtime::{enter, thread_pool}; + + enter::exit(|| thread_pool::block_in_place(f)) +} + +/// Run the provided closure on a thread where blocking is acceptable. +/// +/// In general, issuing a blocking call or performing a lot of compute in a future without +/// yielding is not okay, as it may prevent the executor from driving other futures forward. +/// A closure that is run through this method will instead be run on a dedicated thread pool for +/// such blocking tasks without holding up the main futures executor. +/// +/// # Examples +/// +/// ``` +/// use tokio::task; +/// +/// # async fn docs() -> Result<(), Box<dyn std::error::Error>>{ +/// let res = task::spawn_blocking(move || { +/// // do some compute-heavy work or call synchronous code +/// "done computing" +/// }).await?; +/// +/// assert_eq!(res, "done computing"); +/// # Ok(()) +/// # } +/// ``` +pub fn spawn_blocking<F, R>(f: F) -> JoinHandle<R> +where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, +{ + blocking::spawn_blocking(f) +} diff --git a/tokio/src/task/mod.rs b/tokio/src/task/mod.rs index 709be16b..d2025330 100644 --- a/tokio/src/task/mod.rs +++ b/tokio/src/task/mod.rs @@ -1,5 +1,12 @@ //! Asynchronous green-threads. +#[cfg(feature = "blocking")] +mod blocking; +#[cfg(feature = "rt-full")] +pub use blocking::block_in_place; +#[cfg(feature = "blocking")] +pub use blocking::spawn_blocking; + mod core; use self::core::Cell; pub(crate) use self::core::Header; diff --git a/tokio/tests/rt_threaded.rs b/tokio/tests/rt_threaded.rs index 7daf331b..8be6d036 100644 --- a/tokio/tests/rt_threaded.rs +++ b/tokio/tests/rt_threaded.rs @@ -268,7 +268,7 @@ fn blocking() { for _ in 0..4 { let block = block.clone(); rt.spawn(async move { - tokio::blocking::in_place(move || { + tokio::task::block_in_place(move || { block.wait(); block.wait(); }) |