| #![deny( |
| missing_docs, |
| missing_debug_implementations, |
| rust_2018_idioms, |
| unused_imports, |
| dead_code |
| )] |
| #![cfg_attr(docsrs, feature(doc_cfg))] |
| // Disallow warnings when running tests. |
| #![cfg_attr(test, deny(warnings))] |
| // Disallow warnings in examples. |
| #![doc(test(attr(deny(warnings))))] |
| |
| //! Mio is a fast, low-level I/O library for Rust focusing on non-blocking APIs |
| //! and event notification for building high performance I/O apps with as little |
| //! overhead as possible over the OS abstractions. |
| //! |
| //! # Usage |
| //! |
| //! Using Mio starts by creating a [`Poll`], which reads events from the OS and |
| //! puts them into [`Events`]. You can handle I/O events from the OS with it. |
| //! |
| //! For more detail, see [`Poll`]. |
| //! |
| //! [`Poll`]: ../mio/struct.Poll.html |
| //! [`Events`]: ../mio/event/struct.Events.html |
| //! |
| //! ## Examples |
| //! |
| //! Examples can found in the `examples` directory of the source code, or [on |
| //! GitHub]. |
| //! |
| //! [on GitHub]: https://github.com/tokio-rs/mio/tree/master/examples |
| //! |
| //! ## Guide |
| //! |
| //! A getting started guide is available in the [`guide`] module. |
| //! |
| //! ## Available features |
| //! |
| //! The available features are described in the [`features`] module. |
| |
| // macros used internally |
| #[macro_use] |
| mod macros; |
| |
| mod interest; |
| mod poll; |
| mod sys; |
| mod token; |
| mod waker; |
| |
| pub mod event; |
| |
| cfg_io_source! { |
| mod io_source; |
| } |
| |
| cfg_net! { |
| pub mod net; |
| } |
| |
| #[doc(no_inline)] |
| pub use event::Events; |
| pub use interest::Interest; |
| pub use poll::{Poll, Registry}; |
| pub use token::Token; |
| pub use waker::Waker; |
| |
| #[cfg(all(unix, feature = "os-ext"))] |
| #[cfg_attr(docsrs, doc(cfg(all(unix, feature = "os-ext"))))] |
| pub mod unix { |
| //! Unix only extensions. |
| |
| pub mod pipe { |
| //! Unix pipe. |
| //! |
| //! See the [`new`] function for documentation. |
| |
| pub use crate::sys::pipe::{new, Receiver, Sender}; |
| } |
| |
| pub use crate::sys::SourceFd; |
| } |
| |
| #[cfg(all(windows, feature = "os-ext"))] |
| #[cfg_attr(docsrs, doc(cfg(all(windows, feature = "os-ext"))))] |
| pub mod windows { |
| //! Windows only extensions. |
| |
| pub use crate::sys::named_pipe::NamedPipe; |
| } |
| |
| pub mod features { |
| //! # Mio's optional features. |
| //! |
| //! This document describes the available features in Mio. |
| //! |
| #![cfg_attr(feature = "os-poll", doc = "## `os-poll` (enabled)")] |
| #![cfg_attr(not(feature = "os-poll"), doc = "## `os-poll` (disabled)")] |
| //! |
| //! Mio by default provides only a shell implementation, that `panic!`s the |
| //! moment it is actually run. To run it requires OS support, this is |
| //! enabled by activating the `os-poll` feature. |
| //! |
| //! This makes `Poll`, `Registry` and `Waker` functional. |
| //! |
| #![cfg_attr(feature = "os-ext", doc = "## `os-ext` (enabled)")] |
| #![cfg_attr(not(feature = "os-ext"), doc = "## `os-ext` (disabled)")] |
| //! |
| //! `os-ext` enables additional OS specific facilities. These facilities can |
| //! be found in the `unix` and `windows` module. |
| //! |
| #![cfg_attr(feature = "net", doc = "## Network types (enabled)")] |
| #![cfg_attr(not(feature = "net"), doc = "## Network types (disabled)")] |
| //! |
| //! The `net` feature enables networking primitives in the `net` module. |
| } |
| |
| pub mod guide { |
| //! # Getting started guide. |
| //! |
| //! In this guide we'll do the following: |
| //! |
| //! 1. Create a [`Poll`] instance (and learn what it is). |
| //! 2. Register an [event source]. |
| //! 3. Create an event loop. |
| //! |
| //! At the end you'll have a very small (but quick) TCP server that accepts |
| //! connections and then drops (disconnects) them. |
| //! |
| //! ## 1. Creating a `Poll` instance |
| //! |
| //! Using Mio starts by creating a [`Poll`] instance, which monitors events |
| //! from the OS and puts them into [`Events`]. This allows us to execute I/O |
| //! operations based on what operations are ready. |
| //! |
| //! [`Poll`]: ../struct.Poll.html |
| //! [`Events`]: ../event/struct.Events.html |
| //! |
| #![cfg_attr(feature = "os-poll", doc = "```")] |
| #![cfg_attr(not(feature = "os-poll"), doc = "```ignore")] |
| //! # use mio::{Poll, Events}; |
| //! # fn main() -> std::io::Result<()> { |
| //! // `Poll` allows for polling of readiness events. |
| //! let poll = Poll::new()?; |
| //! // `Events` is collection of readiness `Event`s and can be filled by |
| //! // calling `Poll::poll`. |
| //! let events = Events::with_capacity(128); |
| //! # drop((poll, events)); |
| //! # Ok(()) |
| //! # } |
| //! ``` |
| //! |
| //! For example if we're using a [`TcpListener`], we'll only want to |
| //! attempt to accept an incoming connection *iff* any connections are |
| //! queued and ready to be accepted. We don't want to waste our time if no |
| //! connections are ready. |
| //! |
| //! [`TcpListener`]: ../net/struct.TcpListener.html |
| //! |
| //! ## 2. Registering event source |
| //! |
| //! After we've created a [`Poll`] instance that monitors events from the OS |
| //! for us, we need to provide it with a source of events. This is done by |
| //! registering an [event source]. As the name “event source” suggests it is |
| //! a source of events which can be polled using a `Poll` instance. On Unix |
| //! systems this is usually a file descriptor, or a socket/handle on |
| //! Windows. |
| //! |
| //! In the example below we'll use a [`TcpListener`] for which we'll receive |
| //! an event (from [`Poll`]) once a connection is ready to be accepted. |
| //! |
| //! [event source]: ../event/trait.Source.html |
| //! |
| #![cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")] |
| #![cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")] |
| //! # use mio::net::TcpListener; |
| //! # use mio::{Poll, Token, Interest}; |
| //! # fn main() -> std::io::Result<()> { |
| //! # let poll = Poll::new()?; |
| //! # let address = "127.0.0.1:0".parse().unwrap(); |
| //! // Create a `TcpListener`, binding it to `address`. |
| //! let mut listener = TcpListener::bind(address)?; |
| //! |
| //! // Next we register it with `Poll` to receive events for it. The `SERVER` |
| //! // `Token` is used to determine that we received an event for the listener |
| //! // later on. |
| //! const SERVER: Token = Token(0); |
| //! poll.registry().register(&mut listener, SERVER, Interest::READABLE)?; |
| //! # Ok(()) |
| //! # } |
| //! ``` |
| //! |
| //! Multiple event sources can be [registered] (concurrently), so we can |
| //! monitor multiple sources at a time. |
| //! |
| //! [registered]: ../struct.Registry.html#method.register |
| //! |
| //! ## 3. Creating the event loop |
| //! |
| //! After we've created a [`Poll`] instance and registered one or more |
| //! [event sources] with it, we can [poll] it for events. Polling for events |
| //! is simple, we need a container to store the events: [`Events`] and need |
| //! to do something based on the polled events (this part is up to you, we |
| //! can't do it all!). If we do this in a loop we've got ourselves an event |
| //! loop. |
| //! |
| //! The example below shows the event loop in action, completing our small |
| //! TCP server. |
| //! |
| //! [poll]: ../struct.Poll.html#method.poll |
| //! [event sources]: ../event/trait.Source.html |
| //! |
| #![cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")] |
| #![cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")] |
| //! # use std::io; |
| //! # use std::time::Duration; |
| //! # use mio::net::TcpListener; |
| //! # use mio::{Poll, Token, Interest, Events}; |
| //! # fn main() -> io::Result<()> { |
| //! # let mut poll = Poll::new()?; |
| //! # let mut events = Events::with_capacity(128); |
| //! # let address = "127.0.0.1:0".parse().unwrap(); |
| //! # let mut listener = TcpListener::bind(address)?; |
| //! # const SERVER: Token = Token(0); |
| //! # poll.registry().register(&mut listener, SERVER, Interest::READABLE)?; |
| //! // Start our event loop. |
| //! loop { |
| //! // Poll the OS for events, waiting at most 100 milliseconds. |
| //! poll.poll(&mut events, Some(Duration::from_millis(100)))?; |
| //! |
| //! // Process each event. |
| //! for event in events.iter() { |
| //! // We can use the token we previously provided to `register` to |
| //! // determine for which type the event is. |
| //! match event.token() { |
| //! SERVER => loop { |
| //! // One or more connections are ready, so we'll attempt to |
| //! // accept them (in a loop). |
| //! match listener.accept() { |
| //! Ok((connection, address)) => { |
| //! println!("Got a connection from: {}", address); |
| //! # drop(connection); |
| //! }, |
| //! // A "would block error" is returned if the operation |
| //! // is not ready, so we'll stop trying to accept |
| //! // connections. |
| //! Err(ref err) if would_block(err) => break, |
| //! Err(err) => return Err(err), |
| //! } |
| //! } |
| //! # _ => unreachable!(), |
| //! } |
| //! } |
| //! # return Ok(()); |
| //! } |
| //! |
| //! fn would_block(err: &io::Error) -> bool { |
| //! err.kind() == io::ErrorKind::WouldBlock |
| //! } |
| //! # } |
| //! ``` |
| } |