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 #![no_std] 85 #![doc(test( 86 no_crate_inject, 87 attr( 88 deny(warnings, rust_2018_idioms, single_use_lifetimes), 89 allow(dead_code, unused_assignments, unused_variables) 90 ) 91 ))] 92 #![warn(missing_docs, unsafe_op_in_unsafe_fn)] 93 #![cfg_attr(docsrs, feature(doc_cfg))] 94 95 #[cfg(all(feature = "bilock", not(feature = "unstable")))] 96 compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features"); 97 98 #[doc(no_inline)] 99 pub use futures_core::future::{Future, TryFuture}; 100 #[doc(no_inline)] 101 pub use futures_util::future::{FutureExt, TryFutureExt}; 102 103 #[doc(no_inline)] 104 pub use futures_core::stream::{Stream, TryStream}; 105 #[doc(no_inline)] 106 pub use futures_util::stream::{StreamExt, TryStreamExt}; 107 108 #[doc(no_inline)] 109 pub use futures_sink::Sink; 110 #[doc(no_inline)] 111 pub use futures_util::sink::SinkExt; 112 113 #[cfg(feature = "std")] 114 #[doc(no_inline)] 115 pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; 116 #[cfg(feature = "std")] 117 #[doc(no_inline)] 118 pub use futures_util::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; 119 120 // Macro reexports 121 pub use futures_core::ready; // Readiness propagation 122 pub use futures_util::pin_mut; 123 #[cfg(feature = "std")] 124 #[cfg(feature = "async-await")] 125 pub use futures_util::select; 126 #[cfg(feature = "async-await")] 127 pub use futures_util::{join, pending, poll, select_biased, try_join}; // Async-await 128 129 // Module reexports 130 #[doc(inline)] 131 pub use futures_util::{future, never, sink, stream, task}; 132 133 #[cfg(feature = "std")] 134 #[cfg(feature = "async-await")] 135 pub use futures_util::stream_select; 136 137 #[cfg(feature = "alloc")] 138 #[doc(inline)] 139 pub use futures_channel as channel; 140 #[cfg(feature = "alloc")] 141 #[doc(inline)] 142 pub use futures_util::lock; 143 144 #[cfg(feature = "std")] 145 #[doc(inline)] 146 pub use futures_util::io; 147 148 #[cfg(feature = "executor")] 149 #[cfg_attr(docsrs, doc(cfg(feature = "executor")))] 150 pub mod executor { 151 //! Built-in executors and related tools. 152 //! 153 //! All asynchronous computation occurs within an executor, which is 154 //! capable of spawning futures as tasks. This module provides several 155 //! built-in executors, as well as tools for building your own. 156 //! 157 //! 158 //! This module is only available when the `executor` feature of this 159 //! library is activated. 160 //! 161 //! # Using a thread pool (M:N task scheduling) 162 //! 163 //! Most of the time tasks should be executed on a [thread pool](ThreadPool). 164 //! A small set of worker threads can handle a very large set of spawned tasks 165 //! (which are much lighter weight than threads). Tasks spawned onto the pool 166 //! with the [`spawn_ok`](ThreadPool::spawn_ok) function will run ambiently on 167 //! the created threads. 168 //! 169 //! # Spawning additional tasks 170 //! 171 //! Tasks can be spawned onto a spawner by calling its [`spawn_obj`] method 172 //! directly. In the case of `!Send` futures, [`spawn_local_obj`] can be used 173 //! instead. 174 //! 175 //! # Single-threaded execution 176 //! 177 //! In addition to thread pools, it's possible to run a task (and the tasks 178 //! it spawns) entirely within a single thread via the [`LocalPool`] executor. 179 //! Aside from cutting down on synchronization costs, this executor also makes 180 //! it possible to spawn non-`Send` tasks, via [`spawn_local_obj`]. The 181 //! [`LocalPool`] is best suited for running I/O-bound tasks that do relatively 182 //! little work between I/O operations. 183 //! 184 //! There is also a convenience function [`block_on`] for simply running a 185 //! future to completion on the current thread. 186 //! 187 //! [`spawn_obj`]: https://docs.rs/futures/0.3/futures/task/trait.Spawn.html#tymethod.spawn_obj 188 //! [`spawn_local_obj`]: https://docs.rs/futures/0.3/futures/task/trait.LocalSpawn.html#tymethod.spawn_local_obj 189 190 pub use futures_executor::{ 191 block_on, block_on_stream, enter, BlockingStream, Enter, EnterError, LocalPool, 192 LocalSpawner, 193 }; 194 195 #[cfg(feature = "thread-pool")] 196 #[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))] 197 pub use futures_executor::{ThreadPool, ThreadPoolBuilder}; 198 } 199 200 #[cfg(feature = "compat")] 201 #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] 202 pub mod compat { 203 //! Interop between `futures` 0.1 and 0.3. 204 //! 205 //! This module is only available when the `compat` feature of this 206 //! library is activated. 207 208 pub use futures_util::compat::{ 209 Compat, Compat01As03, Compat01As03Sink, CompatSink, Executor01As03, Executor01CompatExt, 210 Executor01Future, Future01CompatExt, Sink01CompatExt, Stream01CompatExt, 211 }; 212 213 #[cfg(feature = "io-compat")] 214 #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] 215 pub use futures_util::compat::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; 216 } 217 218 pub mod prelude { 219 //! A "prelude" for crates using the `futures` crate. 220 //! 221 //! This prelude is similar to the standard library's prelude in that you'll 222 //! almost always want to import its entire contents, but unlike the 223 //! standard library's prelude you'll have to do so manually: 224 //! 225 //! ``` 226 //! # #[allow(unused_imports)] 227 //! use futures::prelude::*; 228 //! ``` 229 //! 230 //! The prelude may grow over time as additional items see ubiquitous use. 231 232 pub use crate::future::{self, Future, TryFuture}; 233 pub use crate::sink::{self, Sink}; 234 pub use crate::stream::{self, Stream, TryStream}; 235 236 #[doc(no_inline)] 237 #[allow(unreachable_pub)] 238 pub use crate::future::{FutureExt as _, TryFutureExt as _}; 239 #[doc(no_inline)] 240 pub use crate::sink::SinkExt as _; 241 #[doc(no_inline)] 242 #[allow(unreachable_pub)] 243 pub use crate::stream::{StreamExt as _, TryStreamExt as _}; 244 245 #[cfg(feature = "std")] 246 pub use crate::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; 247 248 #[cfg(feature = "std")] 249 #[doc(no_inline)] 250 #[allow(unreachable_pub)] 251 pub use crate::io::{ 252 AsyncBufReadExt as _, AsyncReadExt as _, AsyncSeekExt as _, AsyncWriteExt as _, 253 }; 254 } 255