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 shutdown after periods of being 160 //! idle. Once `Runtime` is dropped, all runtime threads are forcibly shutdown. 161 //! Any tasks that have not yet completed will be dropped. 162 //! 163 //! [tasks]: crate::task 164 //! [`Runtime`]: Runtime 165 //! [`tokio::spawn`]: crate::spawn 166 //! [`tokio::main`]: ../attr.main.html 167 //! [runtime builder]: crate::runtime::Builder 168 //! [`Runtime::new`]: crate::runtime::Runtime::new 169 //! [`Builder::threaded_scheduler`]: crate::runtime::Builder::threaded_scheduler 170 //! [`Builder::enable_io`]: crate::runtime::Builder::enable_io 171 //! [`Builder::enable_time`]: crate::runtime::Builder::enable_time 172 //! [`Builder::enable_all`]: crate::runtime::Builder::enable_all 173 174 // At the top due to macros 175 #[cfg(test)] 176 #[cfg(not(tokio_wasm))] 177 #[macro_use] 178 mod tests; 179 180 pub(crate) mod context; 181 182 pub(crate) mod coop; 183 184 pub(crate) mod park; 185 186 mod driver; 187 188 pub(crate) mod scheduler; 189 190 cfg_io_driver_impl! { 191 pub(crate) mod io; 192 } 193 194 cfg_process_driver! { 195 mod process; 196 } 197 198 cfg_time! { 199 pub(crate) mod time; 200 } 201 202 cfg_signal_internal_and_unix! { 203 pub(crate) mod signal; 204 } 205 206 cfg_rt! { 207 pub(crate) mod task; 208 209 mod config; 210 use config::Config; 211 212 mod blocking; 213 #[cfg_attr(tokio_wasi, allow(unused_imports))] 214 pub(crate) use blocking::spawn_blocking; 215 216 cfg_trace! { 217 pub(crate) use blocking::Mandatory; 218 } 219 220 cfg_fs! { 221 pub(crate) use blocking::spawn_mandatory_blocking; 222 } 223 224 mod builder; 225 pub use self::builder::Builder; 226 cfg_unstable! { 227 pub use self::builder::UnhandledPanic; 228 pub use crate::util::rand::RngSeed; 229 } 230 231 mod defer; 232 pub(crate) use defer::Defer; 233 234 mod handle; 235 pub use handle::{EnterGuard, Handle, TryCurrentError}; 236 237 mod runtime; 238 pub use runtime::{Runtime, RuntimeFlavor}; 239 240 mod thread_id; 241 pub(crate) use thread_id::ThreadId; 242 243 cfg_metrics! { 244 mod metrics; 245 pub use metrics::RuntimeMetrics; 246 247 pub(crate) use metrics::{MetricsBatch, SchedulerMetrics, WorkerMetrics}; 248 249 cfg_net! { 250 pub(crate) use metrics::IoDriverMetrics; 251 } 252 } 253 254 cfg_not_metrics! { 255 pub(crate) mod metrics; 256 pub(crate) use metrics::{SchedulerMetrics, WorkerMetrics, MetricsBatch}; 257 } 258 259 /// After thread starts / before thread stops 260 type Callback = std::sync::Arc<dyn Fn() + Send + Sync>; 261 } 262