| 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 |  | 
|---|