//! Abstractions for asynchronous programming. //! //! This crate provides a number of core abstractions for writing asynchronous //! code: //! //! - [Futures](crate::future) are single eventual values produced by //! asynchronous computations. Some programming languages (e.g. JavaScript) //! call this concept "promise". //! - [Streams](crate::stream) represent a series of values //! produced asynchronously. //! - [Sinks](crate::sink) provide support for asynchronous writing of //! data. //! - [Executors](crate::executor) are responsible for running asynchronous //! tasks. //! //! The crate also contains abstractions for [asynchronous I/O](crate::io) and //! [cross-task communication](crate::channel). //! //! Underlying all of this is the *task system*, which is a form of lightweight //! threading. Large asynchronous computations are built up using futures, //! streams and sinks, and then spawned as independent tasks that are run to //! completion, but *do not block* the thread running them. //! //! The following example describes how the task system context is built and used //! within macros and keywords such as async and await!. //! //! ```rust //! # use futures::channel::mpsc; //! # use futures::executor; ///standard executors to provide a context for futures and streams //! # use futures::executor::ThreadPool; //! # use futures::StreamExt; //! # //! fn main() { //! # { //! let pool = ThreadPool::new().expect("Failed to build pool"); //! let (tx, rx) = mpsc::unbounded::(); //! //! // Create a future by an async block, where async is responsible for an //! // implementation of Future. At this point no executor has been provided //! // to this future, so it will not be running. //! let fut_values = async { //! // Create another async block, again where the Future implementation //! // is generated by async. Since this is inside of a parent async block, //! // it will be provided with the executor of the parent block when the parent //! // block is executed. //! // //! // This executor chaining is done by Future::poll whose second argument //! // is a std::task::Context. This represents our executor, and the Future //! // implemented by this async block can be polled using the parent async //! // block's executor. //! let fut_tx_result = async move { //! (0..100).for_each(|v| { //! tx.unbounded_send(v).expect("Failed to send"); //! }) //! }; //! //! // Use the provided thread pool to spawn the generated future //! // responsible for transmission //! pool.spawn_ok(fut_tx_result); //! //! let fut_values = rx //! .map(|v| v * 2) //! .collect(); //! //! // Use the executor provided to this async block to wait for the //! // future to complete. //! fut_values.await //! }; //! //! // Actually execute the above future, which will invoke Future::poll and //! // subsequently chain appropriate Future::poll and methods needing executors //! // to drive all futures. Eventually fut_values will be driven to completion. //! let values: Vec = executor::block_on(fut_values); //! //! println!("Values={:?}", values); //! # } //! # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 //! } //! ``` //! //! The majority of examples and code snippets in this crate assume that they are //! inside an async block as written above. #![cfg_attr(not(feature = "std"), no_std)] #![warn( missing_debug_implementations, missing_docs, rust_2018_idioms, single_use_lifetimes, unreachable_pub )] #![doc(test( no_crate_inject, attr( deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code, unused_assignments, unused_variables) ) ))] #![cfg_attr(docsrs, feature(doc_cfg))] #[cfg(all(feature = "bilock", not(feature = "unstable")))] compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features"); #[doc(no_inline)] pub use futures_core::future::{Future, TryFuture}; #[doc(no_inline)] pub use futures_util::future::{FutureExt, TryFutureExt}; #[doc(no_inline)] pub use futures_core::stream::{Stream, TryStream}; #[doc(no_inline)] pub use futures_util::stream::{StreamExt, TryStreamExt}; #[doc(no_inline)] pub use futures_sink::Sink; #[doc(no_inline)] pub use futures_util::sink::SinkExt; #[cfg(feature = "std")] #[doc(no_inline)] pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; #[cfg(feature = "std")] #[doc(no_inline)] pub use futures_util::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; // Macro reexports pub use futures_core::ready; // Readiness propagation pub use futures_util::pin_mut; #[cfg(feature = "std")] #[cfg(feature = "async-await")] pub use futures_util::select; #[cfg(feature = "async-await")] pub use futures_util::{join, pending, poll, select_biased, try_join}; // Async-await // Module reexports #[doc(inline)] pub use futures_util::{future, never, sink, stream, task}; #[cfg(feature = "std")] #[cfg(feature = "async-await")] pub use futures_util::stream_select; #[cfg(feature = "alloc")] #[doc(inline)] pub use futures_channel as channel; #[cfg(feature = "alloc")] #[doc(inline)] pub use futures_util::lock; #[cfg(feature = "std")] #[doc(inline)] pub use futures_util::io; #[cfg(feature = "executor")] #[cfg_attr(docsrs, doc(cfg(feature = "executor")))] pub mod executor { //! Built-in executors and related tools. //! //! All asynchronous computation occurs within an executor, which is //! capable of spawning futures as tasks. This module provides several //! built-in executors, as well as tools for building your own. //! //! //! This module is only available when the `executor` feature of this //! library is activated. //! //! # Using a thread pool (M:N task scheduling) //! //! Most of the time tasks should be executed on a [thread pool](ThreadPool). //! A small set of worker threads can handle a very large set of spawned tasks //! (which are much lighter weight than threads). Tasks spawned onto the pool //! with the [`spawn_ok`](ThreadPool::spawn_ok) function will run ambiently on //! the created threads. //! //! # Spawning additional tasks //! //! Tasks can be spawned onto a spawner by calling its [`spawn_obj`] method //! directly. In the case of `!Send` futures, [`spawn_local_obj`] can be used //! instead. //! //! # Single-threaded execution //! //! In addition to thread pools, it's possible to run a task (and the tasks //! it spawns) entirely within a single thread via the [`LocalPool`] executor. //! Aside from cutting down on synchronization costs, this executor also makes //! it possible to spawn non-`Send` tasks, via [`spawn_local_obj`]. The //! [`LocalPool`] is best suited for running I/O-bound tasks that do relatively //! little work between I/O operations. //! //! There is also a convenience function [`block_on`] for simply running a //! future to completion on the current thread. //! //! [`spawn_obj`]: https://docs.rs/futures/0.3/futures/task/trait.Spawn.html#tymethod.spawn_obj //! [`spawn_local_obj`]: https://docs.rs/futures/0.3/futures/task/trait.LocalSpawn.html#tymethod.spawn_local_obj pub use futures_executor::{ block_on, block_on_stream, enter, BlockingStream, Enter, EnterError, LocalPool, LocalSpawner, }; #[cfg(feature = "thread-pool")] #[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))] pub use futures_executor::{ThreadPool, ThreadPoolBuilder}; } #[cfg(feature = "compat")] #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] pub mod compat { //! Interop between `futures` 0.1 and 0.3. //! //! This module is only available when the `compat` feature of this //! library is activated. pub use futures_util::compat::{ Compat, Compat01As03, Compat01As03Sink, CompatSink, Executor01As03, Executor01CompatExt, Executor01Future, Future01CompatExt, Sink01CompatExt, Stream01CompatExt, }; #[cfg(feature = "io-compat")] #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] pub use futures_util::compat::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; } pub mod prelude { //! A "prelude" for crates using the `futures` crate. //! //! This prelude is similar to the standard library's prelude in that you'll //! almost always want to import its entire contents, but unlike the //! standard library's prelude you'll have to do so manually: //! //! ``` //! # #[allow(unused_imports)] //! use futures::prelude::*; //! ``` //! //! The prelude may grow over time as additional items see ubiquitous use. pub use crate::future::{self, Future, TryFuture}; pub use crate::sink::{self, Sink}; pub use crate::stream::{self, Stream, TryStream}; #[doc(no_inline)] #[allow(unreachable_pub)] pub use crate::future::{FutureExt as _, TryFutureExt as _}; #[doc(no_inline)] pub use crate::sink::SinkExt as _; #[doc(no_inline)] #[allow(unreachable_pub)] pub use crate::stream::{StreamExt as _, TryStreamExt as _}; #[cfg(feature = "std")] pub use crate::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; #[cfg(feature = "std")] #[doc(no_inline)] #[allow(unreachable_pub)] pub use crate::io::{ AsyncBufReadExt as _, AsyncReadExt as _, AsyncSeekExt as _, AsyncWriteExt as _, }; }