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