[−][src]Crate mio_st
A fast, low-level IO library for Rust focusing on non-blocking APIs, event notification for building high performance I/O apps.
Goals
- Fast - minimal overhead over the equivalent OS facilities (epoll, kqueue, etc.).
- Zero allocations at runtime.
- A scalable readiness-based API.
- Provide utilities such as a timers.
Usage
Using mio starts by creating a Poller
, which used to poll events, both
from the OS (backed by epoll, kqueue, etc.) and from user space.
For more detail, including supported platforms, see Poller
.
Undefined behaviour
It is undefined how Poller
will behave after a process is forked, if you
need fork a process do it before creating a Poller
instance.
As this is the single threaded version of mio, no types implement Sync
or Send
and sharing these types across threads will result in undefined
behaviour.
Examples
A simple TCP server.
use std::io; use std::collections::HashMap; use mio_st::event::{Events, EventedId}; use mio_st::net::{TcpListener, TcpStream}; use mio_st::poll::{Poller, PollOption}; // An unique id to associate an event with a handle, in this case for our // TCP listener. const SERVER_ID: EventedId = EventedId(0); // Create a `Poller` instance. let mut poller = Poller::new()?; // Also create a container for all events. let mut events = Events::new(); // Setup the server listener. let address = "127.0.0.1:12345".parse()?; let mut server = TcpListener::bind(address)?; // Register our TCP listener with `Poller`, this allows us to receive // notifications about incoming connections. poller.register(&mut server, SERVER_ID, TcpListener::INTERESTS, PollOption::Edge)?; // A hashmap with `EventedId` -> `TcpStream` connections. let mut connections = HashMap::with_capacity(512); // A simple "counter" to create new unique ids for each incoming connection. let mut current_id = EventedId(10); // Start the event loop. loop { // Check for new events. poller.poll(&mut events, None)?; for event in &mut events { // Depending on the event id we need to take an action. match event.id() { SERVER_ID => { // The server is ready to accept one or more connections. accept_connections(&mut server, &mut poller, &mut connections, &mut current_id)?; } connection_id => { // A connection is possibly ready, but it might a spurious // event. let connection = match connections.get_mut(&connection_id) { Some(connection) => connection, // Spurious event, we can safely ignore it. None => continue, }; // Do something with the connection. }, } } } fn accept_connections(server: &mut TcpListener, poller: &mut Poller, connections: &mut HashMap<EventedId, TcpStream>, current_id: &mut EventedId) -> io::Result<()> { // Since we registered with edge-triggered events for our server we need // to accept connections until we hit a would block "error". loop { let (mut connection, address) = match server.accept() { Ok((connection, address)) => (connection, address), Err(ref err) if would_block(err) => return Ok(()), Err(err) => return Err(err), }; // Generate a new id for the connection. let id = *current_id; *current_id = EventedId(current_id.0 + 1); println!("got a new connection from: {}, id: {:?}", address, id); // Register the TCP connection so we can handle events for it as // well. poller.register(&mut connection, id, TcpStream::INTERESTS, PollOption::Edge)?; // Store our connection so we can access it later. connections.insert(id, connection); } } fn would_block(err: &io::Error) -> bool { err.kind() == io::ErrorKind::WouldBlock }
Re-exports
pub use crate::event::EventedId; |
pub use crate::event::Events; |
pub use crate::event::Ready; |
pub use crate::poll::Poller; |
pub use crate::poll::PollOption; |
Modules
event | Readiness event types and utilities. |
net | Networking primitives. |
poll | Types related to polling. |
unix | Unix only extensions. |