axboe / liburing

Library providing helpers for the Linux kernel io_uring support
MIT License
2.89k stars 407 forks source link

io_uring_submit_and_wait_timeout doesn't return -EINTR on signal #1280

Closed noteflakes closed 1 week ago

noteflakes commented 2 weeks ago

I'm using io_uring_submit_and_wait_timeout to submit one or more SQEs and then wait for a single CQE, without timeout or sigmask:

int res = io_uring_submit_and_wait_timeout(ring, &cqe, 1, NULL, NULL);

If interrupted with a SIGINT or SIGTERM, the call will return the number of submitted SQEs instead of -EINTR.

Separating this into separate syscalls:

io_uring_submit(ring);
int res = io_uring_wait_cqe(ring, cqe);

... does return -EINTR.

axboe commented 1 week ago

Not sure much can be done with that - the normal kernel return values are "return an error if an error happened and nothing was successfully done, otherwise return what was processed even if an error was seen". When you combine the two things of submit-and-wait, then yeah you'll get the number submitted return rather than a potential -EINTR as the submission DID get done and occurred before the interruption.

noteflakes commented 1 week ago

Understood. I do the following as a workaround:

struct io_uring_cqe *cqe = NULL;
int res = io_uring_submit_and_wait_timeout(ring, &cqe, 1, NULL, NULL);
if (res > 0 && !cqe) res = -EINTR;

Please let me know if there's a better way to do it.

axboe commented 1 week ago

That should work since you can't get -ETIME here as the timeout is infinite.