• 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 //! # 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