From c0943f99f091bbcc57a93c4533de2e75a9227f90 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Wed, 4 Feb 2026 03:27:46 -0700 Subject: [PATCH] rt: clarify the documentation of `Runtime::spawn` (#7803) --- tokio/src/runtime/handle.rs | 3 ++- tokio/src/runtime/mod.rs | 19 +++++++++++++++++++ tokio/src/runtime/runtime.rs | 3 ++- tokio/src/task/spawn.rs | 11 ++++++++--- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index 1cf9acc19..612bcd2c0 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -166,11 +166,12 @@ impl Handle { /// /// The provided future will start running in the background immediately /// when `spawn` is called, even if you don't await the returned - /// `JoinHandle`. + /// `JoinHandle` (assuming that the runtime [is running][running-runtime]). /// /// See [module level][mod] documentation for more details. /// /// [mod]: index.html + /// [running-runtime]: index.html#driving-the-runtime /// /// # Examples /// diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs index e806c026e..77cf183dc 100644 --- a/tokio/src/runtime/mod.rs +++ b/tokio/src/runtime/mod.rs @@ -205,6 +205,25 @@ //! This is done with [`Builder::enable_io`] and [`Builder::enable_time`]. As a //! shorthand, [`Builder::enable_all`] enables both resource drivers. //! +//! ## Driving the runtime +//! +//! A Tokio runtime can only execute tasks if the runtime is running. Normally +//! this is not an issue as the default configuration of a runtime is always running, +//! but alternate configurations such as the current-thread runtime require that +//! [`Runtime::block_on`] is called. +//! +//! - A multi-threaded runtime is always running because it spawns its own worker +//! threads. +//! - A current-thread runtime does not spawn any worker threads, so it can only +//! execute tasks when you provide a thread by calling [`Runtime::block_on`]. +//! - A [`LocalSet`](crate::task::LocalSet) only executes local tasks spawned on +//! it when the `LocalSet` is `.awaited` or otherwise driven using one of its +//! methods for this purpose. +//! +//! Please be aware that [`Handle::block_on`] does not drive the runtime. +//! There must be at least one call to [`Runtime::block_on`] when using the current +//! thread runtime. [`Handle::block_on`] is not enough. +//! //! ## Lifetime of spawned threads //! //! The runtime may spawn threads depending on its configuration and usage. The diff --git a/tokio/src/runtime/runtime.rs b/tokio/src/runtime/runtime.rs index e967a7e99..b0091bc4b 100644 --- a/tokio/src/runtime/runtime.rs +++ b/tokio/src/runtime/runtime.rs @@ -210,11 +210,12 @@ impl Runtime { /// /// The provided future will start running in the background immediately /// when `spawn` is called, even if you don't await the returned - /// `JoinHandle`. + /// `JoinHandle` (assuming that the runtime [is running][running-runtime]). /// /// See [module level][mod] documentation for more details. /// /// [mod]: index.html + /// [running-runtime]: index.html#driving-the-runtime /// /// # Examples /// diff --git a/tokio/src/task/spawn.rs b/tokio/src/task/spawn.rs index 8ed288034..cd26c6d76 100644 --- a/tokio/src/task/spawn.rs +++ b/tokio/src/task/spawn.rs @@ -6,16 +6,19 @@ use std::future::Future; cfg_rt! { /// Spawns a new asynchronous task, returning a - /// [`JoinHandle`](JoinHandle) for it. + /// [`JoinHandle`] for it. /// /// The provided future will start running in the background immediately /// when `spawn` is called, even if you don't await the returned - /// `JoinHandle`. + /// [`JoinHandle`]. /// /// Spawning a task enables the task to execute concurrently to other tasks. The /// spawned task may execute on the current thread, or it may be sent to a /// different thread to be executed. The specifics depend on the current - /// [`Runtime`](crate::runtime::Runtime) configuration. + /// [`Runtime`](crate::runtime::Runtime) configuration. In a + /// [running runtime][running-runtime], the task will start immediately in the + /// background. On a blocked runtime, the user must drive the runtime forward (for + /// example, by calling [`Runtime::block_on`](crate::runtime::Runtime::block_on)). /// /// It is guaranteed that spawn will not synchronously poll the task being spawned. /// This means that calling spawn while holding a lock does not pose a risk of @@ -29,6 +32,8 @@ cfg_rt! { /// the Tokio runtime are always inside its context, but you can also enter the context /// using the [`Runtime::enter`](crate::runtime::Runtime::enter()) method. /// + /// [running-runtime]: ../runtime/index.html#driving-the-runtime + /// /// # Examples /// /// In this example, a server is started and `spawn` is used to start a new task