1 //! Abstractions for asynchronous programming. 2 //! 3 //! This crate provides a number of core abstractions for writing asynchronous 4 //! code: 5 //! 6 //! - [Futures](crate::future) are single eventual values produced by 7 //! asynchronous computations. Some programming languages (e.g. JavaScript) 8 //! call this concept "promise". 9 //! - [Streams](crate::stream) represent a series of values 10 //! produced asynchronously. 11 //! - [Sinks](crate::sink) provide support for asynchronous writing of 12 //! data. 13 //! - [Executors](crate::executor) are responsible for running asynchronous 14 //! tasks. 15 //! 16 //! The crate also contains abstractions for [asynchronous I/O](crate::io) and 17 //! [cross-task communication](crate::channel). 18 //! 19 //! Underlying all of this is the *task system*, which is a form of lightweight 20 //! threading. Large asynchronous computations are built up using futures, 21 //! streams and sinks, and then spawned as independent tasks that are run to 22 //! completion, but *do not block* the thread running them. 23 //! 24 //! The following example describes how the task system context is built and used 25 //! within macros and keywords such as async and await!. 26 //! 27 //! ```rust 28 //! # use futures::channel::mpsc; 29 //! # use futures::executor; ///standard executors to provide a context for futures and streams 30 //! # use futures::executor::ThreadPool; 31 //! # use futures::StreamExt; 32 //! # 33 //! fn main() { 34 //! # { 35 //! let pool = ThreadPool::new().expect("Failed to build pool"); 36 //! let (tx, rx) = mpsc::unbounded::<i32>(); 37 //! 38 //! // Create a future by an async block, where async is responsible for an 39 //! // implementation of Future. At this point no executor has been provided 40 //! // to this future, so it will not be running. 41 //! let fut_values = async { 42 //! // Create another async block, again where the Future implementation 43 //! // is generated by async. Since this is inside of a parent async block, 44 //! // it will be provided with the executor of the parent block when the parent 45 //! // block is executed. 46 //! // 47 //! // This executor chaining is done by Future::poll whose second argument 48 //! // is a std::task::Context. This represents our executor, and the Future 49 //! // implemented by this async block can be polled using the parent async 50 //! // block's executor. 51 //! let fut_tx_result = async move { 52 //! (0..100).for_each(|v| { 53 //! tx.unbounded_send(v).expect("Failed to send"); 54 //! }) 55 //! }; 56 //! 57 //! // Use the provided thread pool to spawn the generated future 58 //! // responsible for transmission 59 //! pool.spawn_ok(fut_tx_result); 60 //! 61 //! let fut_values = rx 62 //! .map(|v| v * 2) 63 //! .collect(); 64 //! 65 //! // Use the executor provided to this async block to wait for the 66 //! // future to complete. 67 //! fut_values.await 68 //! }; 69 //! 70 //! // Actually execute the above future, which will invoke Future::poll and 71 //! // subsequently chain appropriate Future::poll and methods needing executors 72 //! // to drive all futures. Eventually fut_values will be driven to completion. 73 //! let values: Vec<i32> = executor::block_on(fut_values); 74 //! 75 //! println!("Values={:?}", values); 76 //! # } 77 //! # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 78 //! } 79 //! ``` 80 //! 81 //! The majority of examples and code snippets in this crate assume that they are 82 //! inside an async block as written above. 83 84 #![cfg_attr(not(feature = "std"), no_std)] 85 #![warn( 86 missing_debug_implementations, 87 missing_docs, 88 rust_2018_idioms, 89 single_use_lifetimes, 90 unreachable_pub 91 )] 92 #![doc(test( 93 no_crate_inject, 94 attr( 95 deny(warnings, rust_2018_idioms, single_use_lifetimes), 96 allow(dead_code, unused_assignments, unused_variables) 97 ) 98 ))] 99 #![cfg_attr(docsrs, feature(doc_cfg))] 100 101 #[cfg(all(feature = "bilock", not(feature = "unstable")))] 102 compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features"); 103 104 #[doc(no_inline)] 105 pub use futures_core::future::{Future, TryFuture}; 106 #[doc(no_inline)] 107 pub use futures_util::future::{FutureExt, TryFutureExt}; 108 109 #[doc(no_inline)] 110 pub use futures_core::stream::{Stream, TryStream}; 111 #[doc(no_inline)] 112 pub use futures_util::stream::{StreamExt, TryStreamExt}; 113 114 #[doc(no_inline)] 115 pub use futures_sink::Sink; 116 #[doc(no_inline)] 117 pub use futures_util::sink::SinkExt; 118 119 #[cfg(feature = "std")] 120 #[doc(no_inline)] 121 pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; 122 #[cfg(feature = "std")] 123 #[doc(no_inline)] 124 pub use futures_util::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; 125 126 // Macro reexports 127 pub use futures_core::ready; // Readiness propagation 128 pub use futures_util::pin_mut; 129 #[cfg(feature = "std")] 130 #[cfg(feature = "async-await")] 131 pub use futures_util::select; 132 #[cfg(feature = "async-await")] 133 pub use futures_util::{join, pending, poll, select_biased, try_join}; // Async-await 134 135 // Module reexports 136 #[doc(inline)] 137 pub use futures_util::{future, never, sink, stream, task}; 138 139 #[cfg(feature = "std")] 140 #[cfg(feature = "async-await")] 141 pub use futures_util::stream_select; 142 143 #[cfg(feature = "alloc")] 144 #[doc(inline)] 145 pub use futures_channel as channel; 146 #[cfg(feature = "alloc")] 147 #[doc(inline)] 148 pub use futures_util::lock; 149 150 #[cfg(feature = "std")] 151 #[doc(inline)] 152 pub use futures_util::io; 153 154 #[cfg(feature = "executor")] 155 #[cfg_attr(docsrs, doc(cfg(feature = "executor")))] 156 pub mod executor { 157 //! Built-in executors and related tools. 158 //! 159 //! All asynchronous computation occurs within an executor, which is 160 //! capable of spawning futures as tasks. This module provides several 161 //! built-in executors, as well as tools for building your own. 162 //! 163 //! 164 //! This module is only available when the `executor` feature of this 165 //! library is activated. 166 //! 167 //! # Using a thread pool (M:N task scheduling) 168 //! 169 //! Most of the time tasks should be executed on a [thread pool](ThreadPool). 170 //! A small set of worker threads can handle a very large set of spawned tasks 171 //! (which are much lighter weight than threads). Tasks spawned onto the pool 172 //! with the [`spawn_ok`](ThreadPool::spawn_ok) function will run ambiently on 173 //! the created threads. 174 //! 175 //! # Spawning additional tasks 176 //! 177 //! Tasks can be spawned onto a spawner by calling its [`spawn_obj`] method 178 //! directly. In the case of `!Send` futures, [`spawn_local_obj`] can be used 179 //! instead. 180 //! 181 //! # Single-threaded execution 182 //! 183 //! In addition to thread pools, it's possible to run a task (and the tasks 184 //! it spawns) entirely within a single thread via the [`LocalPool`] executor. 185 //! Aside from cutting down on synchronization costs, this executor also makes 186 //! it possible to spawn non-`Send` tasks, via [`spawn_local_obj`]. The 187 //! [`LocalPool`] is best suited for running I/O-bound tasks that do relatively 188 //! little work between I/O operations. 189 //! 190 //! There is also a convenience function [`block_on`] for simply running a 191 //! future to completion on the current thread. 192 //! 193 //! [`spawn_obj`]: https://docs.rs/futures/0.3/futures/task/trait.Spawn.html#tymethod.spawn_obj 194 //! [`spawn_local_obj`]: https://docs.rs/futures/0.3/futures/task/trait.LocalSpawn.html#tymethod.spawn_local_obj 195 196 pub use futures_executor::{ 197 block_on, block_on_stream, enter, BlockingStream, Enter, EnterError, LocalPool, 198 LocalSpawner, 199 }; 200 201 #[cfg(feature = "thread-pool")] 202 #[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))] 203 pub use futures_executor::{ThreadPool, ThreadPoolBuilder}; 204 } 205 206 #[cfg(feature = "compat")] 207 #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] 208 pub mod compat { 209 //! Interop between `futures` 0.1 and 0.3. 210 //! 211 //! This module is only available when the `compat` feature of this 212 //! library is activated. 213 214 pub use futures_util::compat::{ 215 Compat, Compat01As03, Compat01As03Sink, CompatSink, Executor01As03, Executor01CompatExt, 216 Executor01Future, Future01CompatExt, Sink01CompatExt, Stream01CompatExt, 217 }; 218 219 #[cfg(feature = "io-compat")] 220 #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] 221 pub use futures_util::compat::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; 222 } 223 224 pub mod prelude { 225 //! A "prelude" for crates using the `futures` crate. 226 //! 227 //! This prelude is similar to the standard library's prelude in that you'll 228 //! almost always want to import its entire contents, but unlike the 229 //! standard library's prelude you'll have to do so manually: 230 //! 231 //! ``` 232 //! # #[allow(unused_imports)] 233 //! use futures::prelude::*; 234 //! ``` 235 //! 236 //! The prelude may grow over time as additional items see ubiquitous use. 237 238 pub use crate::future::{self, Future, TryFuture}; 239 pub use crate::sink::{self, Sink}; 240 pub use crate::stream::{self, Stream, TryStream}; 241 242 #[doc(no_inline)] 243 #[allow(unreachable_pub)] 244 pub use crate::future::{FutureExt as _, TryFutureExt as _}; 245 #[doc(no_inline)] 246 pub use crate::sink::SinkExt as _; 247 #[doc(no_inline)] 248 #[allow(unreachable_pub)] 249 pub use crate::stream::{StreamExt as _, TryStreamExt as _}; 250 251 #[cfg(feature = "std")] 252 pub use crate::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; 253 254 #[cfg(feature = "std")] 255 #[doc(no_inline)] 256 #[allow(unreachable_pub)] 257 pub use crate::io::{ 258 AsyncBufReadExt as _, AsyncReadExt as _, AsyncSeekExt as _, AsyncWriteExt as _, 259 }; 260 } 261