Expand description

UringReactor

Read/Write buffer management.

There are two key issues managing asynchronous IO buffers in rust.

  1. The kernel has a mutable reference to the memory until the completion is returned. Rust must not have any references to it during that time.
  2. The memory must remain valid as long as the kernel has a reference to it.

The kernel’s mutable borrow of the buffer

Because the buffers used for read and write must be passed to the kernel for an unknown duration, the functions must maintain ownership of the memory. The core of this problem is that the lifetime of the future isn’t tied to the scope in which the kernel can modify the buffer the future has a reference to. The buffer can be modified at any point from submission until the operation completes. The operation can’t be synchronously canceled when the future is dropped, and Drop can’t be used for safety guarantees. To ensure this never happens, only memory that implements BackingMemory is accepted. For implementors of BackingMemory the mut borrow isn’t an issue because those are already Ok with external modifications to the memory (Like a VolatileSlice).

Buffer lifetime

What if the kernel’s reference to the buffer outlives the buffer itself? This could happen if a read operation was submitted, then the memory is dropped. To solve this, the executor takes an Arc to the backing memory. Vecs being read to are also wrapped in an Arc before being passed to the executor. The executor holds the Arc and ensures all operations are complete before dropping it, that guarantees the memory is valid for the duration.

The buffers have to be on the heap. Because we don’t have a way to cancel a future if it is dropped(can’t rely on drop running), there is no way to ensure the kernel’s buffer remains valid until the operation completes unless the executor holds an Arc to the memory on the heap.

Using Vec for reads/writes.

There is a convenience wrapper VecIoWrapper provided for fully owned vectors. This type ensures that only the kernel is allowed to access the Vec and wraps the the Vec in an Arc to ensure it lives long enough.

Structs

OpData 🔒
Ring 🔒
Reactor that manages async IO work using io_uring.

Enums

Constants

Statics

Functions

Type Definitions