Skip to content

Commit

Permalink
add iouring waitid operation
Browse files Browse the repository at this point in the history
  • Loading branch information
psnszsn committed Feb 13, 2024
1 parent 4e67818 commit 5e5c1a7
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/backend/io_uring.zig
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ pub const Loop = struct {
},

.cancel => |v| linux.io_uring_prep_cancel(sqe, @intCast(@intFromPtr(v.c)), 0),
.waitid => |v| linux.io_uring_prep_waitid(sqe, v.id_type, v.id, v.infop, v.options, 0),
}

// Our sqe user data always points back to the completion.
Expand Down Expand Up @@ -789,6 +790,13 @@ pub const Completion = struct {
else => |errno| std.os.unexpectedErrno(errno),
},
},

.waitid => .{
.waitid = if (res >= 0) {} else switch (@as(std.os.E, @enumFromInt(-res))) {
.CHILD => error.NotFound,
else => |errno| std.os.unexpectedErrno(errno),
},
},
};

return self.callback(self.userdata, loop, self, result);
Expand Down Expand Up @@ -873,6 +881,9 @@ pub const OperationType = enum {

/// Cancel an existing operation.
cancel,

/// Waitid
waitid,
};

/// The result type based on the operation type. For a callback, the
Expand All @@ -895,6 +906,7 @@ pub const Result = union(OperationType) {
timer: TimerError!TimerTrigger,
timer_remove: TimerRemoveError!void,
cancel: CancelError!void,
waitid: WaitidError!void,
};

/// All the supported operations of this event loop. These are always
Expand Down Expand Up @@ -996,6 +1008,13 @@ pub const Operation = union(OperationType) {
cancel: struct {
c: *Completion,
},

waitid: struct {
id_type: linux.P,
id: i32,
infop: *linux.siginfo_t,
options: u32,
},
};

/// ReadBuffer are the various options for reading.
Expand Down Expand Up @@ -1093,6 +1112,11 @@ pub const TimerRemoveError = error{
Unexpected,
};

pub const WaitidError = error{
NotFound,
Unexpected,
};

pub const TimerTrigger = enum {
/// Timer completed due to linked request completing in time.
request,
Expand Down Expand Up @@ -1769,3 +1793,47 @@ test "io_uring: socket read cancellation" {
try testing.expectEqual(OperationType.read, @as(OperationType, read_result));
try testing.expectError(error.Canceled, read_result.read);
}

test "io_uring: waitid" {
const testing = std.testing;

if (@import("builtin").os.isAtLeast(.linux, .{ .major = 6, .minor = 7, .patch = 0 }) == false) {
return error.SkipZigTest;
}

var loop = try Loop.init(.{});
defer loop.deinit();

const pid = try std.os.fork();
if (pid == 0) {
std.os.exit(7);
}
var siginfo: std.os.siginfo_t = undefined;
var waitid_error: ?WaitidError = null;
var c_waitid = Completion{
.op = .{
.waitid = .{
.id_type = .ALL,
.id = -1,
.infop = &siginfo,
.options = std.os.W.EXITED,
},
},
.userdata = &waitid_error,
.callback = (struct {
fn callback(ud: ?*anyopaque, _: *xev.Loop, _: *xev.Completion, r: xev.Result) xev.CallbackAction {
const ptr = @as(*?WaitidError, @ptrCast(@alignCast(ud.?)));
r.waitid catch |err| {
ptr.* = err;
};
return .disarm;
}
}).callback,
};
loop.add(&c_waitid);
try loop.run(.until_done);

try testing.expectEqual(null, waitid_error);
try testing.expectEqual(pid, siginfo.fields.common.first.piduid.pid);
try testing.expectEqual(7, siginfo.fields.common.second.sigchld.status);
}

0 comments on commit 5e5c1a7

Please sign in to comment.