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