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