Skip to main content

IoUringSubmit

Trait IoUringSubmit 

Source
pub trait IoUringSubmit: Send + Sync {
    // Required methods
    fn probe(&self, opcode: u8) -> bool;
    unsafe fn submit(
        &self,
        sqe: Entry,
    ) -> impl Future<Output = Result<i32>> + Send + '_;
}
Expand description

Trait for submitting io-uring operations.

Required Methods§

Source

fn probe(&self, opcode: u8) -> bool

Returns whether the given opcode is supported by the ring.

Source

unsafe fn submit( &self, sqe: Entry, ) -> impl Future<Output = Result<i32>> + Send + '_

Submits an io-uring SQE for asynchronous execution.

Returns a future that completes with the IO result. The future aborts the process if dropped while the IO is in flight, since there is no way to synchronously cancel an in-flight io-uring operation.

§Safety

All memory referenced by the SQE must remain valid for the lifetime of the returned future.

This can be hard to do safely; in particular, if this future can be leaked (via std::mem::forget or otherwise) then the caller must ensure that any referenced memory also leaks. The easiest way to do that is to ensure that the future is awaited in an async function or block that owns the underlying memory. So, this is safe:

async fn write(uring: &impl IoUringSubmit, file: &File, buf: Vec<u8>) -> io::Result<usize> {
    let sqe = opcode::Write::new(
        types::Fd(file.as_raw_fd()), buf.as_ptr(), buf.len() as u32,
    ).build();
    // SAFETY: `buf` is owned by this async function's state machine.
    // If the outer future is leaked, `buf` leaks with it, so the
    // memory remains valid for the io-uring operation.
    unsafe { uring.submit(sqe).await? };
    Ok(buf.len())
}

But this is not:

async fn write(uring: &impl IoUringSubmit, file: &File, buf: &[u8]) -> io::Result<usize> {
    let sqe = opcode::Write::new(
        types::Fd(file.as_raw_fd()), buf.as_ptr(), buf.len() as u32,
    ).build();
    // NOT SAFE: `buf` is a borrow. If the outer future is leaked,
    // the referent can be freed while the io-uring operation is
    // still in flight.
    unsafe { uring.submit(sqe).await? };
    Ok(buf.len())
}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§