Skip to content

Commit

Permalink
io_uring: retry on EINTR
Browse files Browse the repository at this point in the history
We previously treated all errors as final in the loop tick.
Specifically, EINTR needs to be retried. For a long-running application,
EINTR can easily happen if the process running goes to sleep while
sitting in the io_uring syscall.
  • Loading branch information
mitchellh committed Sep 3, 2023
1 parent be725f8 commit 9068c5d
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/backend/io_uring.zig
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,27 @@ pub const Loop = struct {
// of the submit call, because then we can do exactly once syscall
// to get all our events.
if (self.submissions.empty()) {
_ = try self.ring.submit_and_wait(wait);
_ = self.ring.submit_and_wait(wait) catch |err| switch (err) {
error.SignalInterrupt => continue,
else => return err,
};
} else {
// We have submissions, meaning we have to do multiple submissions
// anyways so we always just do non-waiting ones.
_ = try self.submit();
_ = self.submit() catch |err| switch (err) {
error.SignalInterrupt => continue,
else => return err,
};
}

// Wait for completions...
const count = self.ring.copy_cqes(&cqes, wait) catch |err| return err;
const count = self.ring.copy_cqes(&cqes, wait) catch |err| switch (err) {
// EINTR means our blocking syscall was interrupted by some
// process signal. We just retry when we can. See signal(7).
error.SignalInterrupt => continue,
else => return err,
};

for (cqes[0..count]) |cqe| {
const c = @as(?*Completion, @ptrFromInt(@as(usize, @intCast(cqe.user_data)))) orelse continue;
self.active -= 1;
Expand Down

0 comments on commit 9068c5d

Please sign in to comment.