[go: up one dir, main page]

io-uring 0.3.3

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

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


#[test]
fn test_poll_add() -> anyhow::Result<()> {
    let mut ring = 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 {
        ring
            .submission()
            .available()
            .push(entry.build().user_data(0x42))
            .ok()
            .expect("queue is full");
    }

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

    nix::unistd::write(wp.as_raw_fd(), b"pipe")?;
    ring.submit_and_wait(1)?;
    let entry = ring
        .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 ring = 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 {
        ring
            .submission()
            .available()
            .push(entry.build().user_data(token))
            .ok()
            .expect("queue is full");
    }

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

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

    ring.submit()?;

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

    ring.submit_and_wait(2)?;

    let mut cqes = ring
        .completion()
        .available()
        .collect::<Vec<_>>();
    cqes.sort_by_key(|cqe| cqe.user_data());

    match check_kernel_support(&ring) {
        KernelSupport::Less => panic!("unsupported"),
        KernelSupport::V54 => assert_eq!(cqes[0].result(), 0),
        KernelSupport::V55 | _ => 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(())
}