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