Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update documentation on block_in_place #3753

Merged
merged 3 commits into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 40 additions & 13 deletions tokio/src/task/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ cfg_rt_multi_thread! {
/// 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. This function runs the closure on the
/// current thread by having the thread temporarily cease from being a core
/// thread, and turns it into a blocking thread. See the [CPU-bound tasks
/// and blocking code][blocking] section for more information.
///
/// Although this function avoids starving other independently spawned
/// tasks, any other code running concurrently in the same task will be
/// suspended during the call to `block_in_place`. This can happen e.g. when
/// using the [`join!`] macro. To avoid this issue, use [`spawn_blocking`]
/// instead.
///
/// Note that this function can only be used when using the `multi_thread` runtime.
/// future without yielding is problematic, as it may prevent the executor
/// from driving other tasks forward. Calling this function informs the
/// executor that the currently executing task is about to block the thread,
/// so the executor is able to hand off any other tasks it has to a new
/// worker thread before that happens. See the [CPU-bound tasks and blocking
/// code][blocking] section for more information.
///
/// Be aware that although this function avoids starving other independently
/// spawned tasks, any other code running concurrently in the same task will
/// be suspended during the call to `block_in_place`. This can happen e.g.
/// when using the [`join!`] macro. To avoid this issue, use
/// [`spawn_blocking`] instead of `block_in_place`.
///
/// Note that this function cannot be used within a [`current_thread`] runtime
/// because in this case there are no other worker threads to hand off tasks
/// to. On the other hand, calling the function outside a runtime is
/// allowed. In this case, `block_in_place` just calls the provided closure
/// normally.
///
/// Code running behind `block_in_place` cannot be cancelled. When you shut
/// down the executor, it will wait indefinitely for all blocking operations
Expand All @@ -43,6 +48,28 @@ cfg_rt_multi_thread! {
/// });
/// # }
/// ```
///
/// Code running inside `block_in_place` may use `block_on` to reenter the
/// async context.
///
/// ```
/// use tokio::task;
/// use tokio::runtime::Handle;
///
/// # async fn docs() {
/// task::block_in_place(move || {
/// Handle::current().block_on(async move {
/// // do something async
/// });
/// });
/// # }
/// ```
///
/// # Panics
///
/// This function panics if called from a [`current_thread`] runtime.
///
/// [`current_thread`]: fn@crate::runtime::Builder::new_current_thread
pub fn block_in_place<F, R>(f: F) -> R
where
F: FnOnce() -> R,
Expand Down
5 changes: 5 additions & 0 deletions tokio/src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@
//! Instead, Tokio provides two APIs for running blocking operations in an
//! asynchronous context: [`task::spawn_blocking`] and [`task::block_in_place`].
//!
//! Be aware that if you call a non-async method from async code, that non-async
//! method is still inside the asynchronous context, so you should also avoid
//! blocking operations there. This includes destructors of objects destroyed in
//! async code.
//!
//! #### spawn_blocking
//!
//! The `task::spawn_blocking` function is similar to the `task::spawn` function
Expand Down