Skip to content

Commit fad5e7a

Browse files
authored
Merge pull request #18898 from psnszsn/iouring_waitid
io_uring: add waitid operation
2 parents 0c1b999 + d278990 commit fad5e7a

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

lib/std/os/linux.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4300,6 +4300,13 @@ pub const IORING_OP = enum(u8) {
43004300
URING_CMD,
43014301
SEND_ZC,
43024302
SENDMSG_ZC,
4303+
READ_MULTISHOT,
4304+
WAITID,
4305+
FUTEX_WAIT,
4306+
FUTEX_WAKE,
4307+
FUTEX_WAITV,
4308+
FIXED_FD_INSTALL,
4309+
FTRUNCATE,
43034310

43044311
_,
43054312
};

lib/std/os/linux/io_uring.zig

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,23 @@ pub const IO_Uring = struct {
11141114
return sqe;
11151115
}
11161116

1117+
/// Queues (but does not submit) an SQE to perform a `waitid(2)`.
1118+
/// Returns a pointer to the SQE.
1119+
pub fn waitid(
1120+
self: *IO_Uring,
1121+
user_data: u64,
1122+
id_type: linux.P,
1123+
id: i32,
1124+
infop: *linux.siginfo_t,
1125+
options: u32,
1126+
flags: u32,
1127+
) !*linux.io_uring_sqe {
1128+
const sqe = try self.get_sqe();
1129+
io_uring_prep_waitid(sqe, id_type, id, infop, options, flags);
1130+
sqe.user_data = user_data;
1131+
return sqe;
1132+
}
1133+
11171134
/// Registers an array of file descriptors.
11181135
/// Every time a file descriptor is put in an SQE and submitted to the kernel, the kernel must
11191136
/// retrieve a reference to the file, and once I/O has completed the file reference must be
@@ -1962,6 +1979,19 @@ pub fn io_uring_prep_socket_direct_alloc(
19621979
__io_uring_set_target_fixed_file(sqe, linux.IORING_FILE_INDEX_ALLOC);
19631980
}
19641981

1982+
pub fn io_uring_prep_waitid(
1983+
sqe: *linux.io_uring_sqe,
1984+
id_type: linux.P,
1985+
id: i32,
1986+
infop: *linux.siginfo_t,
1987+
options: u32,
1988+
flags: u32,
1989+
) void {
1990+
io_uring_prep_rw(.WAITID, sqe, id, 0, @intFromEnum(id_type), @intFromPtr(infop));
1991+
sqe.rw_flags = flags;
1992+
sqe.splice_fd_in = @bitCast(options);
1993+
}
1994+
19651995
test "structs/offsets/entries" {
19661996
if (builtin.os.tag != .linux) return error.SkipZigTest;
19671997

@@ -4148,6 +4178,32 @@ test "openat_direct/close_direct" {
41484178
try ring.unregister_files();
41494179
}
41504180

4181+
test "waitid" {
4182+
try skipKernelLessThan(.{ .major = 6, .minor = 7, .patch = 0 });
4183+
4184+
var ring = IO_Uring.init(16, 0) catch |err| switch (err) {
4185+
error.SystemOutdated => return error.SkipZigTest,
4186+
error.PermissionDenied => return error.SkipZigTest,
4187+
else => return err,
4188+
};
4189+
defer ring.deinit();
4190+
4191+
const pid = try os.fork();
4192+
if (pid == 0) {
4193+
os.exit(7);
4194+
}
4195+
4196+
var siginfo: os.siginfo_t = undefined;
4197+
_ = try ring.waitid(0, .PID, pid, &siginfo, os.W.EXITED, 0);
4198+
4199+
try testing.expectEqual(1, try ring.submit());
4200+
4201+
const cqe_waitid = try ring.copy_cqe();
4202+
try testing.expectEqual(0, cqe_waitid.res);
4203+
try testing.expectEqual(pid, siginfo.fields.common.first.piduid.pid);
4204+
try testing.expectEqual(7, siginfo.fields.common.second.sigchld.status);
4205+
}
4206+
41514207
/// For use in tests. Returns SkipZigTest is kernel version is less than required.
41524208
inline fn skipKernelLessThan(required: std.SemanticVersion) !void {
41534209
if (builtin.os.tag != .linux) return error.SkipZigTest;

0 commit comments

Comments
 (0)