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.
# fn main() -> Result<(), Box<std::error::Error>> {
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};
const SERVER_ID: EventedId = EventedId(0);
let mut poller = Poller::new()?;
let mut events = Events::new();
let address = "127.0.0.1:12345".parse()?;
let mut server = TcpListener::bind(address)?;
poller.register(&mut server, SERVER_ID, TcpListener::INTERESTS, PollOption::Edge)?;
let mut connections = HashMap::with_capacity(512);
let mut current_id = EventedId(10);
# let i = 0;
loop {
# if i == 0 { break; }
poller.poll(&mut events, None)?;
for event in &mut events {
match event.id() {
SERVER_ID => {
accept_connections(&mut server, &mut poller, &mut connections, &mut current_id)?;
}
connection_id => {
let connection = match connections.get_mut(&connection_id) {
Some(connection) => connection,
None => continue,
};
# drop(connection)
},
}
}
}
fn accept_connections(server: &mut TcpListener, poller: &mut Poller, connections: &mut HashMap<EventedId, TcpStream>, current_id: &mut EventedId) -> io::Result<()> {
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),
};
let id = *current_id;
*current_id = EventedId(current_id.0 + 1);
println!("got a new connection from: {}, id: {:?}", address, id);
poller.register(&mut connection, id, TcpStream::INTERESTS, PollOption::Edge)?;
connections.insert(id, connection);
}
}
fn would_block(err: &io::Error) -> bool {
err.kind() == io::ErrorKind::WouldBlock
}
# Ok(())
# }