broker_tokio/io/mod.rs
1#![cfg_attr(loom, allow(dead_code, unreachable_pub))]
2
3//! Traits, helpers, and type definitions for asynchronous I/O functionality.
4//!
5//! This module is the asynchronous version of `std::io`. Primarily, it
6//! defines two traits, [`AsyncRead`] and [`AsyncWrite`], which are asynchronous
7//! versions of the [`Read`] and [`Write`] traits in the standard library.
8//!
9//! # AsyncRead and AsyncWrite
10//!
11//! Like the standard library's [`Read`] and [`Write`] traits, [`AsyncRead`] and
12//! [`AsyncWrite`] provide the most general interface for reading and writing
13//! input and output. Unlike the standard library's traits, however, they are
14//! _asynchronous_ — meaning that reading from or writing to a `tokio::io`
15//! type will _yield_ to the Tokio scheduler when IO is not ready, rather than
16//! blocking. This allows other tasks to run while waiting on IO.
17//!
18//! Another difference is that [`AsyncRead`] and [`AsyncWrite`] only contain
19//! core methods needed to provide asynchronous reading and writing
20//! functionality. Instead, utility methods are defined in the [`AsyncReadExt`]
21//! and [`AsyncWriteExt`] extension traits. These traits are automatically
22//! implemented for all values that implement [`AsyncRead`] and [`AsyncWrite`]
23//! respectively.
24//!
25//! End users will rarely interact directly with [`AsyncRead`] and
26//! [`AsyncWrite`]. Instead, they will use the async functions defined in the
27//! extension traits. Library authors are expected to implement [`AsyncRead`]
28//! and [`AsyncWrite`] in order to provide types that behave like byte streams.
29//!
30//! Even with these differences, Tokio's [`AsyncRead`] and [`AsyncWrite`] traits
31//! can be used in almost exactly the same manner as the standard library's
32//! `Read` and `Write`. Most types in the standard library that implement `Read`
33//! and `Write` have asynchronous equivalents in `tokio` that implement
34//! `AsyncRead` and `AsyncWrite`, such as [`File`] and [`TcpStream`].
35//!
36//! For example, the standard library documentation introduces `Read` by
37//! [demonstrating][std_example] reading some bytes from a [`std::fs::File`]. We
38//! can do the same with [`tokio::fs::File`][`File`]:
39//!
40//! ```no_run
41//! use tokio::io::{self, AsyncReadExt};
42//! use tokio::fs::File;
43//!
44//! #[tokio::main]
45//! async fn main() -> io::Result<()> {
46//! let mut f = File::open("foo.txt").await?;
47//! let mut buffer = [0; 10];
48//!
49//! // read up to 10 bytes
50//! let n = f.read(&mut buffer).await?;
51//!
52//! println!("The bytes: {:?}", &buffer[..n]);
53//! Ok(())
54//! }
55//! ```
56//!
57//! [`File`]: crate::fs::File
58//! [`TcpStream`]: crate::net::TcpStream
59//! [`std::fs::File`]: std::fs::File
60//! [std_example]: https://doc.rust-lang.org/std/io/index.html#read-and-write
61//!
62//! ## Buffered Readers and Writers
63//!
64//! Byte-based interfaces are unwieldy and can be inefficient, as we'd need to be
65//! making near-constant calls to the operating system. To help with this,
66//! `std::io` comes with [support for _buffered_ readers and writers][stdbuf],
67//! and therefore, `tokio::io` does as well.
68//!
69//! Tokio provides an async version of the [`std::io::BufRead`] trait,
70//! [`AsyncBufRead`]; and async [`BufReader`] and [`BufWriter`] structs, which
71//! wrap readers and writers. These wrappers use a buffer, reducing the number
72//! of calls and providing nicer methods for accessing exactly what you want.
73//!
74//! For example, [`BufReader`] works with the [`AsyncBufRead`] trait to add
75//! extra methods to any async reader:
76//!
77//! ```no_run
78//! use tokio::io::{self, BufReader, AsyncBufReadExt};
79//! use tokio::fs::File;
80//!
81//! #[tokio::main]
82//! async fn main() -> io::Result<()> {
83//! let f = File::open("foo.txt").await?;
84//! let mut reader = BufReader::new(f);
85//! let mut buffer = String::new();
86//!
87//! // read a line into buffer
88//! reader.read_line(&mut buffer).await?;
89//!
90//! println!("{}", buffer);
91//! Ok(())
92//! }
93//! ```
94//!
95//! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call
96//! to [`write`](crate::io::AsyncWriteExt::write):
97//!
98//! ```no_run
99//! use tokio::io::{self, BufWriter, AsyncWriteExt};
100//! use tokio::fs::File;
101//!
102//! #[tokio::main]
103//! async fn main() -> io::Result<()> {
104//! let f = File::create("foo.txt").await?;
105//! {
106//! let mut writer = BufWriter::new(f);
107//!
108//! // write a byte to the buffer
109//! writer.write(&[42u8]).await?;
110//!
111//! } // the buffer is flushed once writer goes out of scope
112//!
113//! Ok(())
114//! }
115//! ```
116//!
117//! [stdbuf]: https://doc.rust-lang.org/std/io/index.html#bufreader-and-bufwriter
118//! [`std::io::BufRead`]: std::io::BufRead
119//! [`AsyncBufRead`]: crate::io::AsyncBufRead
120//! [`BufReader`]: crate::io::BufReader
121//! [`BufWriter`]: crate::io::BufWriter
122//!
123//! ## Implementing AsyncRead and AsyncWrite
124//!
125//! Because they are traits, we can implement `AsyncRead` and `AsyncWrite` for
126//! our own types, as well. Note that these traits must only be implemented for
127//! non-blocking I/O types that integrate with the futures type system. In
128//! other words, these types must never block the thread, and instead the
129//! current task is notified when the I/O resource is ready.
130//!
131//! # Standard input and output
132//!
133//! Tokio provides asynchronous APIs to standard [input], [output], and [error].
134//! These APIs are very similar to the ones provided by `std`, but they also
135//! implement [`AsyncRead`] and [`AsyncWrite`].
136//!
137//! Note that the standard input / output APIs **must** be used from the
138//! context of the Tokio runtime, as they require Tokio-specific features to
139//! function. Calling these functions outside of a Tokio runtime will panic.
140//!
141//! [input]: fn.stdin.html
142//! [output]: fn.stdout.html
143//! [error]: fn.stderr.html
144//!
145//! # `std` re-exports
146//!
147//! Additionally, [`Error`], [`ErrorKind`], and [`Result`] are re-exported
148//! from `std::io` for ease of use.
149//!
150//! [`AsyncRead`]: trait.AsyncRead.html
151//! [`AsyncWrite`]: trait.AsyncWrite.html
152//! [`Error`]: struct.Error.html
153//! [`ErrorKind`]: enum.ErrorKind.html
154//! [`Result`]: type.Result.html
155//! [`Read`]: std::io::Read
156//! [`Write`]: std::io::Write
157cfg_io_blocking! {
158 pub(crate) mod blocking;
159}
160
161mod async_buf_read;
162pub use self::async_buf_read::AsyncBufRead;
163
164mod async_read;
165pub use self::async_read::AsyncRead;
166
167mod async_seek;
168pub use self::async_seek::AsyncSeek;
169
170mod async_write;
171pub use self::async_write::AsyncWrite;
172
173cfg_io_driver! {
174 pub(crate) mod driver;
175
176 mod poll_evented;
177 pub use poll_evented::PollEvented;
178
179 mod registration;
180 pub use registration::Registration;
181}
182
183cfg_io_std! {
184 mod stderr;
185 pub use stderr::{stderr, Stderr};
186
187 mod stdin;
188 pub use stdin::{stdin, Stdin};
189
190 mod stdout;
191 pub use stdout::{stdout, Stdout};
192}
193
194cfg_io_util! {
195 mod split;
196 pub use split::{split, ReadHalf, WriteHalf};
197
198 pub(crate) mod seek;
199 pub use self::seek::Seek;
200
201 pub(crate) mod util;
202 pub use util::{
203 copy, empty, repeat, sink, AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt, BufReader,
204 BufStream, BufWriter, Copy, Empty, Lines, Repeat, Sink, Split, Take,
205 };
206
207 // Re-export io::Error so that users don't have to deal with conflicts when
208 // `use`ing `tokio::io` and `std::io`.
209 pub use std::io::{Error, ErrorKind, Result};
210}
211
212cfg_not_io_util! {
213 cfg_process! {
214 pub(crate) mod util;
215 }
216}
217
218cfg_io_blocking! {
219 /// Types in this module can be mocked out in tests.
220 mod sys {
221 // TODO: don't rename
222 pub(crate) use crate::runtime::spawn_blocking as run;
223 pub(crate) use crate::task::JoinHandle as Blocking;
224 }
225}