Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling EAGAIN/EWOULDBLOCK #262

Open
jamwaffles opened this issue Mar 4, 2024 · 1 comment
Open

Handling EAGAIN/EWOULDBLOCK #262

jamwaffles opened this issue Mar 4, 2024 · 1 comment

Comments

@jamwaffles
Copy link

I'm running into issues when handling multiple read CQEs simultaneously with for recv in ring.completion() { ... } where the first CQE result() is EWOULDBLOCK (or EAGAIN as they're the same code).

In the io_uring crate is there a way to either

a. Peek for ready CQEs a la io_uring_peek_cqe so I can try to read the CQE in a future iteration or
b. Some configuration flags I can pass so I can wait for the CQEs to be ready with minimal latency?

As I understand it, once a CQE is ready from the ring, it cannot be re-read in a future iteration as the ring pointer is advanced in pop(). Therefore I think the answer to (a.) above is "currently, no". What about option (b.)?

As a secret third option I'd also be willing to tackle some kind of peek functionality myself but I'd need some guidance as all the docs I can find elsewhere use liburing which I don't believe this io_uring impl uses.

@jamwaffles
Copy link
Author

I think I fixed this by requeuing the SQE. A snippet from my much longer and much uglier code:

for recv in unsafe { ring.completion_shared() } {
    let key = recv.user_data();

    if recv.result() == -libc::EWOULDBLOCK {
        // Get RX entry we submitted earlier and resubmit it
        let (rx_entry, _buf) = bufs.get(key as usize).expect("Could not get retry entry");

        while unsafe { ring.submission_shared().push(&rx_entry).is_err() } {
            // If the submission queue is full, flush it to the kernel
            ring.submit().expect("Internal error, failed to submit ops");
        }
    }
}

This feels pretty nasty but it steps around not being able to peek the next CQE. Would love a better way to do it though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant