mio/lib.rs
1#![deny(
2 missing_docs,
3 missing_debug_implementations,
4 rust_2018_idioms,
5 unused_imports,
6 dead_code
7)]
8#![cfg_attr(docsrs, feature(doc_cfg))]
9// Disallow warnings when running tests.
10#![cfg_attr(test, deny(warnings))]
11// Disallow warnings in examples.
12#![doc(test(attr(deny(warnings))))]
13
14//! Mio is a fast, low-level I/O library for Rust focusing on non-blocking APIs
15//! and event notification for building high performance I/O apps with as little
16//! overhead as possible over the OS abstractions.
17//!
18//! # Usage
19//!
20//! Using Mio starts by creating a [`Poll`], which reads events from the OS and
21//! puts them into [`Events`]. You can handle I/O events from the OS with it.
22//!
23//! For more detail, see [`Poll`].
24//!
25//! [`Poll`]: ../mio/struct.Poll.html
26//! [`Events`]: ../mio/event/struct.Events.html
27//!
28//! ## Examples
29//!
30//! Examples can be found in the `examples` directory of the source code, or [on
31//! GitHub].
32//!
33//! [on GitHub]: https://github.com/tokio-rs/mio/tree/master/examples
34//!
35//! ## Guide
36//!
37//! A getting started guide is available in the [`guide`] module.
38//!
39//! ## Available features
40//!
41//! The available features are described in the [`features`] module.
42
43#[cfg(all(target_family = "wasm", not(target_os = "wasi")))]
44compile_error!("This wasm target is unsupported by mio. If using Tokio, disable the net feature.");
45
46// macros used internally
47#[macro_use]
48mod macros;
49
50mod interest;
51mod poll;
52mod sys;
53mod token;
54#[cfg(not(target_os = "wasi"))]
55mod waker;
56
57pub mod event;
58
59cfg_io_source! {
60 mod io_source;
61}
62
63cfg_net! {
64 pub mod net;
65}
66
67#[doc(no_inline)]
68pub use event::Events;
69pub use interest::Interest;
70pub use poll::{Poll, Registry};
71pub use token::Token;
72#[cfg(not(target_os = "wasi"))]
73pub use waker::Waker;
74
75#[cfg(all(unix, feature = "os-ext"))]
76#[cfg_attr(docsrs, doc(cfg(all(unix, feature = "os-ext"))))]
77pub mod unix {
78 //! Unix only extensions.
79
80 pub mod pipe {
81 //! Unix pipe.
82 //!
83 //! See the [`new`] function for documentation.
84
85 pub use crate::sys::pipe::{new, Receiver, Sender};
86 }
87
88 pub use crate::sys::SourceFd;
89}
90
91#[cfg(all(target_os = "hermit", feature = "os-ext"))]
92#[cfg_attr(docsrs, doc(cfg(all(target_os = "hermit", feature = "os-ext"))))]
93pub mod hermit {
94 //! Hermit only extensions.
95
96 pub use crate::sys::SourceFd;
97}
98
99#[cfg(all(target_os = "wasi", not(target_env = "p1"), feature = "os-ext"))]
100#[cfg_attr(docsrs, doc(cfg(all(target_os = "wasi", feature = "os-ext"))))]
101pub mod wasi {
102 //! WASI-only extensions.
103
104 pub use crate::sys::SourceFd;
105}
106
107#[cfg(all(windows, feature = "os-ext"))]
108#[cfg_attr(docsrs, doc(cfg(all(windows, feature = "os-ext"))))]
109pub mod windows {
110 //! Windows only extensions.
111
112 pub use crate::sys::named_pipe::NamedPipe;
113}
114
115pub mod features {
116 //! # Mio's optional features.
117 //!
118 //! This document describes the available features in Mio.
119 //!
120 #![cfg_attr(feature = "os-poll", doc = "## `os-poll` (enabled)")]
121 #![cfg_attr(not(feature = "os-poll"), doc = "## `os-poll` (disabled)")]
122 //!
123 //! Mio by default provides only a shell implementation that `panic!`s the
124 //! moment it is actually run. To run it requires OS support, this is
125 //! enabled by activating the `os-poll` feature.
126 //!
127 //! This makes `Poll`, `Registry` and `Waker` functional.
128 //!
129 #![cfg_attr(feature = "os-ext", doc = "## `os-ext` (enabled)")]
130 #![cfg_attr(not(feature = "os-ext"), doc = "## `os-ext` (disabled)")]
131 //!
132 //! `os-ext` enables additional OS specific facilities. These facilities can
133 //! be found in the `unix` and `windows` module.
134 //!
135 #![cfg_attr(feature = "net", doc = "## Network types (enabled)")]
136 #![cfg_attr(not(feature = "net"), doc = "## Network types (disabled)")]
137 //!
138 //! The `net` feature enables networking primitives in the `net` module.
139}
140
141pub mod guide {
142 //! # Getting started guide.
143 //!
144 //! In this guide we'll do the following:
145 //!
146 //! 1. Create a [`Poll`] instance (and learn what it is).
147 //! 2. Register an [event source].
148 //! 3. Create an event loop.
149 //!
150 //! At the end you'll have a very small (but quick) TCP server that accepts
151 //! connections and then drops (disconnects) them.
152 //!
153 //! ## 1. Creating a `Poll` instance
154 //!
155 //! Using Mio starts by creating a [`Poll`] instance, which monitors events
156 //! from the OS and puts them into [`Events`]. This allows us to execute I/O
157 //! operations based on what operations are ready.
158 //!
159 //! [`Poll`]: ../struct.Poll.html
160 //! [`Events`]: ../event/struct.Events.html
161 //!
162 #![cfg_attr(feature = "os-poll", doc = "```")]
163 #![cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
164 //! # use mio::{Poll, Events};
165 //! # fn main() -> std::io::Result<()> {
166 //! // `Poll` allows for polling of readiness events.
167 //! let poll = Poll::new()?;
168 //! // `Events` is collection of readiness `Event`s and can be filled by
169 //! // calling `Poll::poll`.
170 //! let events = Events::with_capacity(128);
171 //! # drop((poll, events));
172 //! # Ok(())
173 //! # }
174 //! ```
175 //!
176 //! For example if we're using a [`TcpListener`], we'll only want to
177 //! attempt to accept an incoming connection *iff* any connections are
178 //! queued and ready to be accepted. We don't want to waste our time if no
179 //! connections are ready.
180 //!
181 //! [`TcpListener`]: ../net/struct.TcpListener.html
182 //!
183 //! ## 2. Registering event source
184 //!
185 //! After we've created a [`Poll`] instance that monitors events from the OS
186 //! for us, we need to provide it with a source of events. This is done by
187 //! registering an [event source]. As the name “event source” suggests it is
188 //! a source of events which can be polled using a `Poll` instance. On Unix
189 //! systems this is usually a file descriptor, or a socket/handle on
190 //! Windows.
191 //!
192 //! In the example below we'll use a [`TcpListener`] for which we'll receive
193 //! an event (from [`Poll`]) once a connection is ready to be accepted.
194 //!
195 //! [event source]: ../event/trait.Source.html
196 //!
197 #![cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")]
198 #![cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")]
199 //! # use mio::net::TcpListener;
200 //! # use mio::{Poll, Token, Interest};
201 //! # fn main() -> std::io::Result<()> {
202 //! # let poll = Poll::new()?;
203 //! # let address = "127.0.0.1:0".parse().unwrap();
204 //! // Create a `TcpListener`, binding it to `address`.
205 //! let mut listener = TcpListener::bind(address)?;
206 //!
207 //! // Next we register it with `Poll` to receive events for it. The `SERVER`
208 //! // `Token` is used to determine that we received an event for the listener
209 //! // later on.
210 //! const SERVER: Token = Token(0);
211 //! poll.registry().register(&mut listener, SERVER, Interest::READABLE)?;
212 //! # Ok(())
213 //! # }
214 //! ```
215 //!
216 //! Multiple event sources can be [registered] (concurrently), so we can
217 //! monitor multiple sources at a time.
218 //!
219 //! [registered]: ../struct.Registry.html#method.register
220 //!
221 //! ## 3. Creating the event loop
222 //!
223 //! After we've created a [`Poll`] instance and registered one or more
224 //! [event sources] with it, we can [poll] it for events. Polling for events
225 //! is simple, we need a container to store the events: [`Events`] and need
226 //! to do something based on the polled events (this part is up to you, we
227 //! can't do it all!). If we do this in a loop we've got ourselves an event
228 //! loop.
229 //!
230 //! The example below shows the event loop in action, completing our small
231 //! TCP server.
232 //!
233 //! [poll]: ../struct.Poll.html#method.poll
234 //! [event sources]: ../event/trait.Source.html
235 //!
236 #![cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")]
237 #![cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")]
238 //! # use std::io;
239 //! # use std::time::Duration;
240 //! # use mio::net::TcpListener;
241 //! # use mio::{Poll, Token, Interest, Events};
242 //! # fn main() -> io::Result<()> {
243 //! # let mut poll = Poll::new()?;
244 //! # let mut events = Events::with_capacity(128);
245 //! # let address = "127.0.0.1:0".parse().unwrap();
246 //! # let mut listener = TcpListener::bind(address)?;
247 //! # const SERVER: Token = Token(0);
248 //! # poll.registry().register(&mut listener, SERVER, Interest::READABLE)?;
249 //! // Start our event loop.
250 //! loop {
251 //! // Poll the OS for events, waiting at most 100 milliseconds.
252 //! poll.poll(&mut events, Some(Duration::from_millis(100)))?;
253 //!
254 //! // Process each event.
255 //! for event in events.iter() {
256 //! // We can use the token we previously provided to `register` to
257 //! // determine for which type the event is.
258 //! match event.token() {
259 //! SERVER => loop {
260 //! // One or more connections are ready, so we'll attempt to
261 //! // accept them (in a loop).
262 //! match listener.accept() {
263 //! Ok((connection, address)) => {
264 //! println!("Got a connection from: {}", address);
265 //! # drop(connection);
266 //! },
267 //! // A "would block error" is returned if the operation
268 //! // is not ready, so we'll stop trying to accept
269 //! // connections.
270 //! Err(ref err) if would_block(err) => break,
271 //! Err(err) => return Err(err),
272 //! }
273 //! }
274 //! # _ => unreachable!(),
275 //! }
276 //! }
277 //! # return Ok(());
278 //! }
279 //!
280 //! fn would_block(err: &io::Error) -> bool {
281 //! err.kind() == io::ErrorKind::WouldBlock
282 //! }
283 //! # }
284 //! ```
285}