linux-io-uring 0.1.0

The `io_uring` library for Rust.
Documentation
mod common;

use std::os::unix::io::AsRawFd;
use linux_io_uring::opcode::{ self, types };
use linux_io_uring::IoUring;
use common::Fd;


#[test]
fn test_poll_add() -> anyhow::Result<()> {
    let mut io_uring = IoUring::new(1)?;
    let (rp, wp) = nix::unistd::pipe()?;
    let (rp, wp) = (Fd(rp), Fd(wp));

    let entry = opcode::PollAdd::new(
        types::Target::Fd(rp.as_raw_fd()),
        libc::POLLIN
    );
    unsafe {
        io_uring
            .submission()
            .available()
            .push(entry.build().user_data(0x42))
            .ok()
            .expect("queue is full");
    }

    io_uring.submit()?;
    assert!(io_uring.completion().is_empty());

    nix::unistd::write(wp.as_raw_fd(), b"pipe")?;
    io_uring.submit_and_wait(1)?;
    let entry = io_uring
        .completion()
        .available()
        .next()
        .expect("queue is empty");
    assert_eq!(entry.result() as i16 & libc::POLLIN, libc::POLLIN);
    assert_eq!(entry.user_data(), 0x42);

    Ok(())
}

#[test]
fn test_poll_remove() -> anyhow::Result<()> {
    let mut io_uring = IoUring::new(1)?;
    let (rp, wp) = nix::unistd::pipe()?;
    let (rp, wp) = (Fd(rp), Fd(wp));

    let token = 0x43;

    let entry = opcode::PollAdd::new(
        types::Target::Fd(rp.as_raw_fd()),
        libc::POLLIN
    );
    unsafe {
        io_uring
            .submission()
            .available()
            .push(entry.build().user_data(token))
            .ok()
            .expect("queue is full");
    }

    io_uring.submit()?;
    assert!(io_uring.completion().is_empty());

    let entry = opcode::PollRemove::new(token);
    unsafe {
        io_uring
            .submission()
            .available()
            .push(entry.build().user_data(0x44))
            .ok()
            .expect("queue is full");
    }

    io_uring.submit()?;

    nix::unistd::write(wp.as_raw_fd(), b"pipe")?;

    io_uring.submit_and_wait(2)?;

    let mut cqes = io_uring
        .completion()
        .available()
        .collect::<Vec<_>>();
    cqes.sort_by_key(|cqe| cqe.user_data());
    assert_eq!(cqes[0].result(), -libc::ECANCELED);
    assert_eq!(cqes[0].user_data(), token);
    assert_eq!(cqes[1].result(), 0);
    assert_eq!(cqes[1].user_data(), 0x44);

    Ok(())
}