pub fn get_sqe(self: *IoUring) !*linux.io_uring_sqe self: *IoUring139
140
141
142
143
144
145
146
147
148pub fn get_sqe(self: *IoUring) !*linux.io_uring_sqe {
const head = @atomicLoad(u32, self.sq.head, .acquire);
// Remember that these head and tail offsets wrap around every four billion operations.
// We must therefore use wrapping addition and subtraction to avoid a runtime crash.
const next = self.sq.sqe_tail +% 1;
if (next -% head > self.sq.sqes.len) return error.SubmissionQueueFull;
const sqe = &self.sq.sqes[self.sq.sqe_tail & self.sq.mask];
self.sq.sqe_tail = next;
return sqe;
}
Returns a pointer to a vacant SQE, or an error if the submission queue is full. We follow the implementation (and atomics) of liburing's
io_uring_get_sqe()exactly. However, instead of a null we return an error to force safe handling. Any situation where the submission queue is full tends more towards a control flow error, and the null return in liburing is more a C idiom than anything else, for lack of a better alternative. In Zig, we have first-class error handling... so let's use it. Matches the implementation of io_uring_get_sqe() in liburing.