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