# 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.8](https://docs.rs/mio/^0.8)
* [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.8"
```

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 (API level 21)
* DragonFly BSD
* FreeBSD
* Linux
* NetBSD
* OpenBSD
* Windows
* iOS
* macOS
* Wine (version 6.11+, see [issue #1444])

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
[issue #1444]: https://github.com/tokio-rs/mio/issues/1444

### Unsupported

* Haiku, see [issue #1472]
* Solaris, see [issue #1152]

[issue #1472]: https://github.com/tokio-rs/mio/issues/1472
[issue #1152]: https://github.com/tokio-rs/mio/issues/1152

## 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).
