feature. See also
. The project being documented here (as the example) is the Zig library itself.
Uring.futexWait
fn futexWait(
userdata: ?*anyopaque,
ptr: *const u32,
expected: u32,
timeout: Io.Timeout,
) Io.Cancelable!void
File
Code
fn futexWait(
userdata: ?*anyopaque,
ptr: *const u32,
expected: u32,
timeout: Io.Timeout,
) Io.Cancelable!void {
const ev: *Evented = @ptrCast(@alignCast(userdata));
const timespec: ?linux.kernel_timespec, const clock: Io.Clock, const timeout_flags: u32 = timespec: switch (timeout) {
.none => .{
null,
.awake,
linux.IORING_TIMEOUT_ABS,
},
.duration => |duration| {
const ns = duration.raw.toNanoseconds();
break :timespec .{
.{
.sec = @intCast(@divFloor(ns, std.time.ns_per_s)),
.nsec = @intCast(@mod(ns, std.time.ns_per_s)),
},
duration.clock,
0,
};
},
.deadline => |deadline| {
const ns = deadline.raw.toNanoseconds();
break :timespec .{
.{
.sec = @intCast(@divFloor(ns, std.time.ns_per_s)),
.nsec = @intCast(@mod(ns, std.time.ns_per_s)),
},
deadline.clock,
linux.IORING_TIMEOUT_ABS,
};
},
};
var cancel_region: CancelRegion = .init();
defer cancel_region.deinit();
const thread = try cancel_region.awaitIoUring();
thread.enqueue().* = .{
.opcode = .FUTEX_WAIT,
.flags = if (timespec) |_| linux.IOSQE_IO_LINK else 0,
.ioprio = 0,
.fd = @bitCast(linux.FUTEX2_FLAGS{ .size = .U32, .private = true }),
.off = expected,
.addr = @intFromPtr(ptr),
.len = 0,
.rw_flags = 0,
.user_data = @intFromPtr(cancel_region.fiber),
.buf_index = 0,
.personality = 0,
.splice_fd_in = 0,
.addr3 = std.math.maxInt(u32),
.resv = 0,
};
if (timespec) |*timespec_ptr| thread.enqueue().* = .{
.opcode = .LINK_TIMEOUT,
.flags = linux.IOSQE_CQE_SKIP_SUCCESS,
.ioprio = 0,
.fd = 0,
.off = 0,
.addr = @intFromPtr(timespec_ptr),
.len = 1,
.rw_flags = timeout_flags | @as(u32, switch (clock) {
.real => linux.IORING_TIMEOUT_REALTIME,
else => 0,
.boot => linux.IORING_TIMEOUT_BOOTTIME,
}),
.user_data = @backingInt(Completion.Userdata.wakeup),
.buf_index = 0,
.personality = 0,
.splice_fd_in = 0,
.addr3 = 0,
.resv = 0,
};
ev.yield(null, .nothing);
switch (cancel_region.errno()) {
.SUCCESS => {},
.INTR, .CANCELED => {},
.AGAIN => {},
.INVAL => {},
.TIMEDOUT => unreachable,
.FAULT => recoverableOsBugDetected(),
else => recoverableOsBugDetected(),
}
}