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