Module rustix::io::epoll

source ·
Expand description

epoll support.

This is an experiment, and it isn’t yet clear whether epoll is the right level of abstraction at which to introduce safety. But it works fairly well in simple examples 🙂.

Examples

use io_lifetimes::AsFd;
use rustix::io::{epoll, ioctl_fionbio, read, write};
use rustix::net::{
    accept, bind_v4, listen, socket, AddressFamily, Ipv4Addr, Protocol, SocketAddrV4,
    SocketType,
};
use std::collections::HashMap;
use std::os::unix::io::AsRawFd;

// Create a socket and listen on it.
let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
bind_v4(&listen_sock, &SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0))?;
listen(&listen_sock, 1)?;

// Create an epoll object. Using `Owning` here means the epoll object will
// take ownership of the file descriptors registered with it.
let epoll = epoll::epoll_create(epoll::CreateFlags::CLOEXEC)?;

// Register the socket with the epoll object.
epoll::epoll_add(&epoll, &listen_sock, 1, epoll::EventFlags::IN)?;

// Keep track of the sockets we've opened.
let mut next_id = 2;
let mut sockets = HashMap::new();

// Process events.
let mut event_list = epoll::EventVec::with_capacity(4);
loop {
    epoll::epoll_wait(&epoll, &mut event_list, -1)?;
    for (_event_flags, target) in &event_list {
        if target == 1 {
            // Accept a new connection, set it to non-blocking, and
            // register to be notified when it's ready to write to.
            let conn_sock = accept(&listen_sock)?;
            ioctl_fionbio(&conn_sock, true)?;
            epoll::epoll_add(
                &epoll,
                &conn_sock,
                next_id,
                epoll::EventFlags::OUT | epoll::EventFlags::ET,
            )?;

            // Keep track of the socket.
            sockets.insert(next_id, conn_sock);
            next_id += 1;
        } else {
            // Write a message to the stream and then unregister it.
            let target = sockets.remove(&target).unwrap();
            write(&target, b"hello\n")?;
            let _ = epoll::epoll_del(&epoll, &target)?;
        }
    }
}

Structs

  • EPOLL_* for use with [Epoll::new].
  • EPOLL* for use with [Epoll::add].
  • A vector of Events, plus context for interpreting them.
  • An iterator over the Events in an EventVec.

Functions

  • epoll_ctl(self, EPOLL_CTL_ADD, data, event)—Adds an element to an Epoll.
  • epoll_create1(flags)—Creates a new Epoll.
  • epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)—Removes an element in this Epoll.
  • epoll_ctl(self, EPOLL_CTL_MOD, target, event)—Modifies an element in this Epoll.
  • epoll_wait(self, events, timeout)—Waits for registered events of interest.