mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-18 00:00:09 +02:00
task: move blocking fns into tokio::task (#1781)
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
{
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
@@ -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(());
|
||||
})
|
||||
});
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user