ringbahn / iou

Rust interface to io_uring
Apache License 2.0
328 stars 22 forks source link

How to concurrent use iou #40

Closed Sherlock-Holo closed 4 years ago

Sherlock-Holo commented 4 years ago

I found almost all api in iou need &mut self, like queues.

it makes me can't use iou concurrently: a thread waiting on wait_for_cqe and another thread use next_sqe and submit.

withoutboats commented 4 years ago

There are two sides of this:

First, you can wrap the ring in a Mutex to allow it to be used from several threads.

Second, the ring supports splitting it into a separate SQ and CQ, which can then be mutated separately.

So you can, for example, have 1 thread which holds the CQ, and another thread which holds the SQ, or you can have many threads sharing the SQ with a mutex while one thread holds the CQ, or you can just have a mutex around the whole ring being shared by many threads.

Sherlock-Holo commented 4 years ago
use once_cell::sync::OnceCell;
use std::sync::Mutex;

static SQ: OnceCell<Mutex<iou::SubmissionQueue<'static>>> = OnceCell::new();

static CQ: OnceCell<Mutex<iou::CompletionQueue<'static>>> = OnceCell::new();

fn get_ring() -> &'static mut iou::IoUring {
    static mut RING: OnceCell<iou::IoUring> = OnceCell::new();

    unsafe {
        RING.get_or_init(|| {
            iou::IoUring::new(1024).unwrap()
        });

        RING.get_mut().unwrap()
    }
}

pub fn get_sq() -> &'static Mutex<iou::SubmissionQueue<'static>> {
    SQ.get_or_init(|| {
        Mutex::new(get_ring().sq())
    })
}

pub fn get_cq() -> &'static Mutex<iou::CompletionQueue<'static>> {
    CQ.get_or_init(|| {
        Mutex::new(get_ring().cq())
    })
}

fn main() {}

If users only use get_sq get_cq, will it be safety? @withoutboats