Skip to content

Commit

Permalink
aio: bsd/darwin ChildExit
Browse files Browse the repository at this point in the history
  • Loading branch information
Cloudef committed Jun 22, 2024
1 parent 47a89fb commit b000797
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 16 deletions.
11 changes: 7 additions & 4 deletions src/aio.zig
Original file line number Diff line number Diff line change
Expand Up @@ -423,17 +423,20 @@ test "SymlinkAt" {
}

test "ChildExit" {
if (@import("builtin").target.os.tag != .linux) {
return error.SkipZigTest;
}
const pid = try std.posix.fork();
if (pid == 0) {
std.time.sleep(1 * std.time.ns_per_s);
std.posix.exit(69);
}
var term: std.process.Child.Term = undefined;
try single(ChildExit{ .child = pid, .out_term = &term });
try std.testing.expectEqual(69, term.Signal);
if (term == .Signal) {
try std.testing.expectEqual(69, term.Signal);
} else if (term == .Exited) {
try std.testing.expectEqual(69, term.Exited);
} else {
unreachable;
}
}

test "Socket" {
Expand Down
2 changes: 1 addition & 1 deletion src/aio/Fallback.zig
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ fn cancelNotThreadSafe(self: *@This(), id: u16) enum { in_progress, not_found, o

fn onThreadExecutor(self: *@This(), id: u16) void {
var failure: Operation.Error = error.Success;
uopUnwrapCall(&self.sq.ops.nodes[id].used, posix.perform, .{}) catch |err| {
uopUnwrapCall(&self.sq.ops.nodes[id].used, posix.perform, .{self.sq.readiness[id]}) catch |err| {
failure = err;
};
self.completion_mutex.lock();
Expand Down
30 changes: 21 additions & 9 deletions src/aio/common/posix.zig
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub inline fn statusToTerm(status: u32) std.process.Child.Term {
.{ .Unknown = status };
}

pub inline fn perform(op: anytype) Operation.Error!void {
pub inline fn perform(op: anytype, readiness: Readiness) Operation.Error!void {
switch (comptime Operation.tagFromPayloadType(@TypeOf(op.*))) {
.fsync => _ = try std.posix.fsync(op.file.handle),
.read => op.out_read.* = try std.posix.pread(op.file.handle, op.buffer, op.offset),
Expand Down Expand Up @@ -190,14 +190,9 @@ pub inline fn perform(op: anytype) Operation.Error!void {
.mkdir_at => _ = try std.posix.mkdiratZ(op.dir.fd, op.path, op.mode),
.symlink_at => _ = try std.posix.symlinkatZ(op.target, op.dir.fd, op.link_path),
.child_exit => {
if (@hasDecl(std.posix.system, "waitid")) {
_ = std.posix.system.waitid(.PID, op.child, @constCast(&op._), std.posix.W.EXITED);
if (op.out_term) |term| {
term.* = statusToTerm(@intCast(op._.fields.common.second.sigchld.status));
}
} else {
@panic("unsupported");
}
_ = readiness; // TODO: prefer pidfd_wait on linux
const res = std.posix.waitpid(op.child, std.posix.W.NOHANG);
if (op.out_term) |term| term.* = statusToTerm(res.status);
},
.socket => op.out_socket.* = try std.posix.socket(op.domain, op.flags, op.protocol),
.close_socket => std.posix.close(op.socket),
Expand Down Expand Up @@ -258,6 +253,23 @@ pub inline fn openReadiness(op: anytype) OpenReadinessError!Readiness {
else => std.posix.unexpectedErrno(e),
};
break :blk .{ .fd = @intCast(res), .mode = .in };
} else if (comptime @hasDecl(std.posix.system, "kqueue")) {
const fd = try std.posix.kqueue();
_ = std.posix.kevent(fd, &.{.{
.ident = @intCast(op.child),
.filter = std.posix.system.EVFILT_PROC,
.flags = std.posix.system.EV_ADD | std.posix.system.EV_ENABLE | std.posix.system.EV_ONESHOT,
.fflags = std.posix.system.NOTE_EXIT,
.data = 0,
.udata = 0,
}}, &.{}, null) catch |err| return switch (err) {
error.EventNotFound => unreachable,
error.ProcessNotFound => unreachable,
error.AccessDenied => unreachable,
error.SystemResources => |e| e,
else => error.Unexpected,
};
break :blk .{ .fd = fd, .mode = .in };
} else {
@panic("unsupported");
}
Expand Down
4 changes: 2 additions & 2 deletions src/aio/ops.zig
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,8 @@ pub const ChildExit = struct {
child: std.process.Child.Id,
out_term: ?*std.process.Child.Term = null,
_: switch (builtin.target.os.tag) {
.windows => @compileError("unsupported"),
else => std.posix.siginfo_t,
.linux => std.posix.siginfo_t, // only required for io_uring
else => void,
} = undefined,
out_id: ?*Id = null,
out_error: ?*Error = null,
Expand Down

0 comments on commit b000797

Please sign in to comment.