diff options
author | Carl Lerche <me@carllerche.com> | 2019-12-06 13:10:18 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-06 13:10:18 -0800 |
commit | a53f94ab61184be1fcd128da0f15a43ad30259e4 (patch) | |
tree | d9b4fda4403cab4d71c9501505aa3233ae836af0 | |
parent | 98c9a77f18a2777c42b2ad603e7c322f75463ca0 (diff) |
doc: expand on runtime / spawn docs (#1914)
-rw-r--r-- | tokio/src/runtime/mod.rs | 10 | ||||
-rw-r--r-- | tokio/src/task/spawn.rs | 73 |
2 files changed, 83 insertions, 0 deletions
diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs index 45c2bd5e..9fb57e14 100644 --- a/tokio/src/runtime/mod.rs +++ b/tokio/src/runtime/mod.rs @@ -161,6 +161,16 @@ //! This is done with [`Builder::enable_io`] and [`Builder::enable_time`]. As a //! shorthand, [`Builder::enable_all`] enables both resource drivers. //! +//! ## Lifetime of spawned threads +//! +//! The runtime may spawn threads depending on its configuration and usage. The +//! threaded scheduler spawns threads to schedule tasks and calls to +//! `spawn_blocking` spawn threads to run blocking operations. +//! +//! While the `Runtime` is active, threads may shutdown after periods of being +//! idle. Once `Runtime` is dropped, all runtime threads are forcibly shutdown. +//! Any tasks that have not yet completed will be dropped. +//! //! [tasks]: crate::task //! [driver]: crate::io::driver //! [executor]: https://tokio.rs/docs/internals/runtime-model/#executors diff --git a/tokio/src/task/spawn.rs b/tokio/src/task/spawn.rs index ab1356c8..131fca5b 100644 --- a/tokio/src/task/spawn.rs +++ b/tokio/src/task/spawn.rs @@ -12,6 +12,10 @@ doc_rt_core! { /// different thread to be executed. The specifics depend on the current /// [`Runtime`](crate::runtime::Runtime) configuration. /// + /// There is no guarantee that a spawned task will execute to completion. + /// When a runtime is shutdown, all outstanding tasks are dropped, + /// regardless of the lifecycle of that task. + /// /// # Examples /// /// In this example, a server is started and `spawn` is used to start a new task @@ -45,6 +49,75 @@ doc_rt_core! { /// # Panics /// /// Panics if called from **outside** of the Tokio runtime. + /// + /// # Using `!Send` values from a task + /// + /// The task supplied to `spawn` must implement `!Send`. However, it is + /// possible to **use** `!Send` values from the task as long as they only + /// exist between calls to `.await`. + /// + /// For example, this will work: + /// + /// ``` + /// use tokio::task; + /// + /// use std::rc::Rc; + /// + /// fn use_rc(rc: Rc<()>) { + /// // Do stuff w/ rc + /// # drop(rc); + /// } + /// + /// #[tokio::main] + /// async fn main() { + /// tokio::spawn(async { + /// // Force the `Rc` to stay in a scope with no `.await` + /// { + /// let rc = Rc::new(()); + /// use_rc(rc.clone()); + /// } + /// + /// task::yield_now().await; + /// }).await.unwrap(); + /// } + /// ``` + /// + /// This will **not** work: + /// + /// ```compile_fail + /// use tokio::task; + /// + /// use std::rc::Rc; + /// + /// fn use_rc(rc: Rc<()>) { + /// // Do stuff w/ rc + /// # drop(rc); + /// } + /// + /// #[tokio::main] + /// async fn main() { + /// tokio::spawn(async { + /// let rc = Rc::new(()); + /// + /// task::yield_now().await; + /// + /// use_rc(rc.clone()); + /// }).await.unwrap(); + /// } + /// ``` + /// + /// Holding on to a `!Send` value across calls to `.await` will result in + /// an unfriendly compile error message similar to: + /// + /// ```text + /// `[... some type ...]` cannot be sent between threads safely + /// ``` + /// + /// or: + /// + /// ```text + /// error[E0391]: cycle detected when processing `main` + /// ``` pub fn spawn<T>(task: T) -> JoinHandle<T::Output> where T: Future + Send + 'static, |