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