1//! The Tokio runtime.
2//!
3//! Unlike other Rust programs, asynchronous applications require runtime
4//! support. In particular, the following runtime services are necessary:
5//!
6//! * An **I/O event loop**, called the driver, which drives I/O resources and
7//! dispatches I/O events to tasks that depend on them.
8//! * A **scheduler** to execute [tasks] that use these I/O resources.
9//! * A **timer** for scheduling work to run after a set period of time.
10//!
11//! Tokio's [`Runtime`] bundles all of these services as a single type, allowing
12//! them to be started, shut down, and configured together. However, often it is
13//! not required to configure a [`Runtime`] manually, and a user may just use the
14//! [`tokio::main`] attribute macro, which creates a [`Runtime`] under the hood.
15//!
16//! # Usage
17//!
18//! When no fine tuning is required, the [`tokio::main`] attribute macro can be
19//! used.
20//!
21//! ```no_run
22//! use tokio::net::TcpListener;
23//! use tokio::io::{AsyncReadExt, AsyncWriteExt};
24//!
25//! #[tokio::main]
26//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
27//! let listener = TcpListener::bind("127.0.0.1:8080").await?;
28//!
29//! loop {
30//! let (mut socket, _) = listener.accept().await?;
31//!
32//! tokio::spawn(async move {
33//! let mut buf = [0; 1024];
34//!
35//! // In a loop, read data from the socket and write the data back.
36//! loop {
37//! let n = match socket.read(&mut buf).await {
38//! // socket closed
39//! Ok(n) if n == 0 => return,
40//! Ok(n) => n,
41//! Err(e) => {
42//! println!("failed to read from socket; err = {:?}", e);
43//! return;
44//! }
45//! };
46//!
47//! // Write the data back
48//! if let Err(e) = socket.write_all(&buf[0..n]).await {
49//! println!("failed to write to socket; err = {:?}", e);
50//! return;
51//! }
52//! }
53//! });
54//! }
55//! }
56//! ```
57//!
58//! From within the context of the runtime, additional tasks are spawned using
59//! the [`tokio::spawn`] function. Futures spawned using this function will be
60//! executed on the same thread pool used by the [`Runtime`].
61//!
62//! A [`Runtime`] instance can also be used directly.
63//!
64//! ```no_run
65//! use tokio::net::TcpListener;
66//! use tokio::io::{AsyncReadExt, AsyncWriteExt};
67//! use tokio::runtime::Runtime;
68//!
69//! fn main() -> Result<(), Box<dyn std::error::Error>> {
70//! // Create the runtime
71//! let rt = Runtime::new()?;
72//!
73//! // Spawn the root task
74//! rt.block_on(async {
75//! let listener = TcpListener::bind("127.0.0.1:8080").await?;
76//!
77//! loop {
78//! let (mut socket, _) = listener.accept().await?;
79//!
80//! tokio::spawn(async move {
81//! let mut buf = [0; 1024];
82//!
83//! // In a loop, read data from the socket and write the data back.
84//! loop {
85//! let n = match socket.read(&mut buf).await {
86//! // socket closed
87//! Ok(n) if n == 0 => return,
88//! Ok(n) => n,
89//! Err(e) => {
90//! println!("failed to read from socket; err = {:?}", e);
91//! return;
92//! }
93//! };
94//!
95//! // Write the data back
96//! if let Err(e) = socket.write_all(&buf[0..n]).await {
97//! println!("failed to write to socket; err = {:?}", e);
98//! return;
99//! }
100//! }
101//! });
102//! }
103//! })
104//! }
105//! ```
106//!
107//! ## Runtime Configurations
108//!
109//! Tokio provides multiple task scheduling strategies, suitable for different
110//! applications. The [runtime builder] or `#[tokio::main]` attribute may be
111//! used to select which scheduler to use.
112//!
113//! #### Multi-Thread Scheduler
114//!
115//! The multi-thread scheduler executes futures on a _thread pool_, using a
116//! work-stealing strategy. By default, it will start a worker thread for each
117//! CPU core available on the system. This tends to be the ideal configuration
118//! for most applications. The multi-thread scheduler requires the `rt-multi-thread`
119//! feature flag, and is selected by default:
120//! ```
121//! use tokio::runtime;
122//!
123//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
124//! let threaded_rt = runtime::Runtime::new()?;
125//! # Ok(()) }
126//! ```
127//!
128//! Most applications should use the multi-thread scheduler, except in some
129//! niche use-cases, such as when running only a single thread is required.
130//!
131//! #### Current-Thread Scheduler
132//!
133//! The current-thread scheduler provides a _single-threaded_ future executor.
134//! All tasks will be created and executed on the current thread. This requires
135//! the `rt` feature flag.
136//! ```
137//! use tokio::runtime;
138//!
139//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
140//! let rt = runtime::Builder::new_current_thread()
141//! .build()?;
142//! # Ok(()) }
143//! ```
144//!
145//! #### Resource drivers
146//!
147//! When configuring a runtime by hand, no resource drivers are enabled by
148//! default. In this case, attempting to use networking types or time types will
149//! fail. In order to enable these types, the resource drivers must be enabled.
150//! This is done with [`Builder::enable_io`] and [`Builder::enable_time`]. As a
151//! shorthand, [`Builder::enable_all`] enables both resource drivers.
152//!
153//! ## Lifetime of spawned threads
154//!
155//! The runtime may spawn threads depending on its configuration and usage. The
156//! multi-thread scheduler spawns threads to schedule tasks and for `spawn_blocking`
157//! calls.
158//!
159//! While the `Runtime` is active, threads may shut down after periods of being
160//! idle. Once `Runtime` is dropped, all runtime threads have usually been
161//! terminated, but in the presence of unstoppable spawned work are not
162//! guaranteed to have been terminated. See the
163//! [struct level documentation](Runtime#shutdown) for more details.
164//!
165//! [tasks]: crate::task
166//! [`Runtime`]: Runtime
167//! [`tokio::spawn`]: crate::spawn
168//! [`tokio::main`]: ../attr.main.html
169//! [runtime builder]: crate::runtime::Builder
170//! [`Runtime::new`]: crate::runtime::Runtime::new
171//! [`Builder::threaded_scheduler`]: crate::runtime::Builder::threaded_scheduler
172//! [`Builder::enable_io`]: crate::runtime::Builder::enable_io
173//! [`Builder::enable_time`]: crate::runtime::Builder::enable_time
174//! [`Builder::enable_all`]: crate::runtime::Builder::enable_all
175
176// At the top due to macros
177#[cfg(test)]
178#[cfg(not(tokio_wasm))]
179#[macro_use]
180mod tests;
181
182pub(crate) mod context;
183
184pub(crate) mod coop;
185
186pub(crate) mod park;
187
188mod driver;
189
190pub(crate) mod scheduler;
191
192cfg_io_driver_impl! {
193 pub(crate) mod io;
194}
195
196cfg_process_driver! {
197 mod process;
198}
199
200cfg_time! {
201 pub(crate) mod time;
202}
203
204cfg_signal_internal_and_unix! {
205 pub(crate) mod signal;
206}
207
208cfg_rt! {
209 pub(crate) mod task;
210
211 mod config;
212 use config::Config;
213
214 mod blocking;
215 #[cfg_attr(tokio_wasi, allow(unused_imports))]
216 pub(crate) use blocking::spawn_blocking;
217
218 cfg_trace! {
219 pub(crate) use blocking::Mandatory;
220 }
221
222 cfg_fs! {
223 pub(crate) use blocking::spawn_mandatory_blocking;
224 }
225
226 mod builder;
227 pub use self::builder::Builder;
228 cfg_unstable! {
229 pub use self::builder::UnhandledPanic;
230 pub use crate::util::rand::RngSeed;
231 }
232
233 cfg_taskdump! {
234 pub mod dump;
235 pub use dump::Dump;
236 }
237
238 mod handle;
239 pub use handle::{EnterGuard, Handle, TryCurrentError};
240
241 mod runtime;
242 pub use runtime::{Runtime, RuntimeFlavor};
243
244 mod thread_id;
245 pub(crate) use thread_id::ThreadId;
246
247 cfg_metrics! {
248 mod metrics;
249 pub use metrics::{RuntimeMetrics, HistogramScale};
250
251 pub(crate) use metrics::{MetricsBatch, SchedulerMetrics, WorkerMetrics, HistogramBuilder};
252
253 cfg_net! {
254 pub(crate) use metrics::IoDriverMetrics;
255 }
256 }
257
258 cfg_not_metrics! {
259 pub(crate) mod metrics;
260 pub(crate) use metrics::{SchedulerMetrics, WorkerMetrics, MetricsBatch, HistogramBuilder};
261 }
262
263 /// After thread starts / before thread stops
264 type Callback = std::sync::Arc<dyn Fn() + Send + Sync>;
265}
266