# Mio – Metal IO

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.

[![Crates.io][crates-badge]][crates-url]
[![MIT licensed][mit-badge]][mit-url]
[![Build Status][azure-badge]][azure-url]
[![Build Status][cirrus-badge]][cirrus-url]

[crates-badge]: https://img.shields.io/crates/v/mio.svg
[crates-url]: https://crates.io/crates/mio
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
[mit-url]: LICENSE
[azure-badge]: https://dev.azure.com/tokio-rs/Tokio/_apis/build/status/tokio-rs.mio?branchName=master
[azure-url]: https://dev.azure.com/tokio-rs/Tokio/_build/latest?definitionId=2&branchName=master
[cirrus-badge]: https://api.cirrus-ci.com/github/tokio-rs/mio.svg
[cirrus-url]: https://cirrus-ci.com/github/tokio-rs/mio

**API documentation**

* [master](https://tokio-rs.github.io/mio/doc/mio/)
* [v0.7](https://docs.rs/mio/^0.7)
* [v0.6](https://docs.rs/mio/^0.6)

This is a low level library, if you are looking for something easier to get
started with, see [Tokio](https://tokio.rs).

## Usage

To use `mio`, first add this to your `Cargo.toml`:

```toml
[dependencies]
mio = "0.7"
```

Next we can start using Mio. The following is quick introduction using
`TcpListener` and `TcpStream`. Note that `features = ["os-poll", "net"]` must be
specified for this example.

```rust
use std::error::Error;

use mio::net::{TcpListener, TcpStream};
use mio::{Events, Interest, Poll, Token};

// Some tokens to allow us to identify which event is for which socket.
const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

fn main() -> Result<(), Box<dyn Error>> {
    // Create a poll instance.
    let mut poll = Poll::new()?;
    // Create storage for events.
    let mut events = Events::with_capacity(128);

    // Setup the server socket.
    let addr = "127.0.0.1:13265".parse()?;
    let mut server = TcpListener::bind(addr)?;
    // Start listening for incoming connections.
    poll.registry()
        .register(&mut server, SERVER, Interest::READABLE)?;

    // Setup the client socket.
    let mut client = TcpStream::connect(addr)?;
    // Register the socket.
    poll.registry()
        .register(&mut client, CLIENT, Interest::READABLE | Interest::WRITABLE)?;

    // Start an event loop.
    loop {
        // Poll Mio for events, blocking until we get an event.
        poll.poll(&mut events, None)?;

        // Process each event.
        for event in events.iter() {
            // We can use the token we previously provided to `register` to
            // determine for which socket the event is.
            match event.token() {
                SERVER => {
                    // If this is an event for the server, it means a connection
                    // is ready to be accepted.
                    //
                    // Accept the connection and drop it immediately. This will
                    // close the socket and notify the client of the EOF.
                    let connection = server.accept();
                    drop(connection);
                }
                CLIENT => {
                    if event.is_writable() {
                        // We can (likely) write to the socket without blocking.
                    }

                    if event.is_readable() {
                        // We can (likely) read from the socket without blocking.
                    }

                    // Since the server just shuts down the connection, let's
                    // just exit from our event loop.
                    return Ok(());
                }
                // We don't expect any events with tokens other than those we provided.
                _ => unreachable!(),
            }
        }
    }
}
```

## Features

* Non-blocking TCP, UDP
* I/O event queue backed by epoll, kqueue, and IOCP
* Zero allocations at runtime
* Platform specific extensions

## Non-goals

The following are specifically omitted from Mio and are left to the user
or higher-level libraries.

* File operations
* Thread pools / multi-threaded event loop
* Timers

## Platforms

Currently supported platforms:

* Android
* DragonFly BSD
* FreeBSD
* Linux
* NetBSD
* OpenBSD
* Solaris
* Windows
* iOS
* macOS

There are potentially others. If you find that Mio works on another
platform, submit a PR to update the list!

Mio can handle interfacing with each of the event systems of the aforementioned
platforms. The details of their implementation are further discussed in the
`Poll` type of the API documentation (see above).

The Windows implementation for polling sockets is using the [wepoll] strategy.
This uses the Windows AFD system to access socket readiness events.

[wepoll]: https://github.com/piscisaureus/wepoll

## Community

A group of Mio users hang out on [Discord], this can be a good place to go for
questions.

[Discord]: https://discord.gg/tokio

## Contributing

Interested in getting involved? We would love to help you! For simple
bug fixes, just submit a PR with the fix and we can discuss the fix
directly in the PR. If the fix is more complex, start with an issue.

If you want to propose an API change, create an issue to start a
discussion with the community. Also, feel free to talk with us in Discord.

Finally, be kind. We support the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct).
