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