mio
provides a readiness-based notification API. This means that you will be notified when an IoHandle
is available for reading or writing. When you have been notified that an IoHandle
is ready, you can synchronously read from that handle to get the data.
pub trait Handler<T: Token, M: Send> {
/// A registered IoHandle has available data to read
fn readable(&mut self, reactor: &mut EventLoop<T, M>, hint: ReadHint, token: T);
/// A registered IoHandle is available to write to
fn writable(&mut self, reactor: &mut EventLoop<T, M>, token: T);
// ...
}
The ReadHint
provides additional information about the likely effects of a read(2)
call:
pub enum ReadHint {
/// Data is available to be read
DataHint,
/// The remote end of the socket closed (hung up)
HupHint,
/// Reading will result in an error
ErrorHint,
/// The IO backend does not provide hints
UnknownHint
}
This information can be useful, but it does not alleviate the handler from checking the return value of read(2)
, because a change in status can occur between the time the event was delivered and when the read
call actually took place. It is expected to be used with optimizations that can skip expensive work if an error of hang-up has definitely occurred.
The expected usage pattern is:
mio
(using O_NONBLOCK
or equivalent)read(2)
s until the read
call returns EAGAIN
or EOF
.ReadHint
can proactively notify handlers that EOF
has been reached, but handlers must still handle the
possibility that a read
call returns EOF
. This is why it's provided as a "hint".IoHandle
is available for writing the handle can write(2)
until the write
call returns EAGAIN
.IoHandle
is closed, it is automatically removed from the set of interested IoHandles
(by the kernel). If you
get an unrecoverable error when attempting an IO operation, you should probably close the file descriptor.IoHandle
(via dup(2)
, for example), you will need to ensure that all duplicates are
closed.mio
provides an edge-triggered, multi-shot API, so you don't need to do anything to receive events when an IoHandle
becomes ready again. You will receive the very first notification after registration even if the IoHandle
became ready before registration.