commit 3961fe3de9713e3e618551cd96873a7b3948a2b2 (tree)
parent 2c6304efc798d8a3773ae126661902b3a3214854
Author: Andrew Kelley <andrew@ziglang.org>
Date: Wed, 7 Jan 2026 15:00:01 -0800
std: move posix.kevent to Io.Kqueue
Diffstat:
3 files changed, 59 insertions(+), 58 deletions(-)
diff --git a/lib/std/Build/Watch.zig b/lib/std/Build/Watch.zig
@@ -699,7 +699,7 @@ const Os = switch (builtin.os.tag) {
.data = 0,
.udata = gop.index,
}};
- _ = try posix.kevent(w.os.kq_fd, &changes, &.{}, null);
+ _ = try Io.Kqueue.kevent(w.os.kq_fd, &changes, &.{}, null);
assert(handles.len == gop.index);
try handles.append(gpa, .{
.rs = .{},
@@ -789,7 +789,7 @@ const Os = switch (builtin.os.tag) {
},
};
const filtered_changes = if (i == handles.len - 1) changes[0..1] else &changes;
- _ = try posix.kevent(w.os.kq_fd, filtered_changes, &.{}, null);
+ _ = try Io.Kqueue.kevent(w.os.kq_fd, filtered_changes, &.{}, null);
if (path.sub_path.len != 0) posix.close(dir_fd);
w.dir_table.swapRemoveAt(i);
@@ -803,13 +803,13 @@ const Os = switch (builtin.os.tag) {
fn wait(w: *Watch, gpa: Allocator, timeout: Timeout) !WaitResult {
var timespec_buffer: posix.timespec = undefined;
var event_buffer: [100]posix.Kevent = undefined;
- var n = try posix.kevent(w.os.kq_fd, &.{}, &event_buffer, timeout.toTimespec(×pec_buffer));
+ var n = try Io.Kqueue.kevent(w.os.kq_fd, &.{}, &event_buffer, timeout.toTimespec(×pec_buffer));
if (n == 0) return .timeout;
const reaction_sets = w.os.handles.items(.rs);
var any_dirty = markDirtySteps(gpa, reaction_sets, event_buffer[0..n], false);
timespec_buffer = .{ .sec = 0, .nsec = 0 };
while (n == event_buffer.len) {
- n = try posix.kevent(w.os.kq_fd, &.{}, &event_buffer, ×pec_buffer);
+ n = try Io.Kqueue.kevent(w.os.kq_fd, &.{}, &event_buffer, ×pec_buffer);
if (n == 0) break;
any_dirty = markDirtySteps(gpa, reaction_sets, event_buffer[0..n], any_dirty);
}
diff --git a/lib/std/Io/Kqueue.zig b/lib/std/Io/Kqueue.zig
@@ -334,7 +334,10 @@ fn schedule(k: *Kqueue, thread: *Thread, ready_queue: Fiber.Queue) void {
},
};
// If an error occurs it only pessimises scheduling.
- _ = posix.kevent(idle_search_thread.kq_fd, &changes, &.{}, null) catch {};
+ _ = kevent(idle_search_thread.kq_fd, &changes, &.{}, null) catch |err| {
+ // TODO handle EINTR for cancellation purposes
+ @panic(@errorName(err)); // TODO
+ };
return;
}
spawn_thread: {
@@ -429,9 +432,9 @@ fn idle(k: *Kqueue, thread: *Thread) void {
k.yield(ready_fiber, .nothing);
maybe_ready_fiber = null;
}
- const n = posix.kevent(thread.kq_fd, &.{}, &events_buffer, null) catch |err| {
+ const n = kevent(thread.kq_fd, &.{}, &events_buffer, null) catch |err| {
// TODO handle EINTR for cancellation purposes
- @panic(@errorName(err));
+ @panic(@errorName(err)); // TODO
};
var maybe_ready_queue: ?Fiber.Queue = null;
for (events_buffer[0..n]) |event| switch (@as(Completion.UserData, @enumFromInt(event.udata))) {
@@ -598,8 +601,9 @@ const SwitchMessage = struct {
.udata = @intFromEnum(Completion.UserData.exit),
},
};
- _ = posix.kevent(each_thread.kq_fd, &changes, &.{}, null) catch |err| {
- @panic(@errorName(err));
+ _ = kevent(each_thread.kq_fd, &changes, &.{}, null) catch |err| {
+ // TODO handle EINTR for cancellation purposes
+ @panic(@errorName(err)); // TODO
};
},
}
@@ -1538,7 +1542,8 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea
.udata = @intFromPtr(fiber),
},
};
- assert(0 == (posix.kevent(thread.kq_fd, &changes, &.{}, null) catch |err| {
+ assert(0 == (kevent(thread.kq_fd, &changes, &.{}, null) catch |err| {
+ // TODO handle EINTR for cancellation purposes
@panic(@errorName(err)); // TODO
}));
}
@@ -1774,3 +1779,47 @@ const Condition = struct {
wake: Io.Condition.Wake,
},
};
+
+pub const KEventError = error{
+ /// The process does not have permission to register a filter.
+ AccessDenied,
+ /// The event could not be found to be modified or deleted.
+ EventNotFound,
+ /// No memory was available to register the event.
+ SystemResources,
+ /// The specified process to attach to does not exist.
+ ProcessNotFound,
+ /// changelist or eventlist had too many items on it.
+ /// TODO remove this possibility
+ Overflow,
+};
+
+pub fn kevent(
+ kq: i32,
+ changelist: []const posix.Kevent,
+ eventlist: []posix.Kevent,
+ timeout: ?*const posix.timespec,
+) KEventError!usize {
+ while (true) {
+ const rc = posix.system.kevent(
+ kq,
+ changelist.ptr,
+ std.math.cast(c_int, changelist.len) orelse return error.Overflow,
+ eventlist.ptr,
+ std.math.cast(c_int, eventlist.len) orelse return error.Overflow,
+ timeout,
+ );
+ switch (posix.errno(rc)) {
+ .SUCCESS => return @intCast(rc),
+ .ACCES => return error.AccessDenied,
+ .FAULT => unreachable, // TODO use error.Unexpected for these
+ .BADF => unreachable, // Always a race condition.
+ .INTR => continue, // TODO handle cancelation
+ .INVAL => unreachable,
+ .NOENT => return error.EventNotFound,
+ .NOMEM => return error.SystemResources,
+ .SRCH => return error.ProcessNotFound,
+ else => unreachable,
+ }
+ }
+}
diff --git a/lib/std/posix.zig b/lib/std/posix.zig
@@ -792,54 +792,6 @@ pub fn fstat(fd: fd_t) FStatError!Stat {
}
}
-pub const KEventError = error{
- /// The process does not have permission to register a filter.
- AccessDenied,
-
- /// The event could not be found to be modified or deleted.
- EventNotFound,
-
- /// No memory was available to register the event.
- SystemResources,
-
- /// The specified process to attach to does not exist.
- ProcessNotFound,
-
- /// changelist or eventlist had too many items on it.
- /// TODO remove this possibility
- Overflow,
-};
-
-pub fn kevent(
- kq: i32,
- changelist: []const Kevent,
- eventlist: []Kevent,
- timeout: ?*const timespec,
-) KEventError!usize {
- while (true) {
- const rc = system.kevent(
- kq,
- changelist.ptr,
- cast(c_int, changelist.len) orelse return error.Overflow,
- eventlist.ptr,
- cast(c_int, eventlist.len) orelse return error.Overflow,
- timeout,
- );
- switch (errno(rc)) {
- .SUCCESS => return @intCast(rc),
- .ACCES => return error.AccessDenied,
- .FAULT => unreachable,
- .BADF => unreachable, // Always a race condition.
- .INTR => continue,
- .INVAL => unreachable,
- .NOENT => return error.EventNotFound,
- .NOMEM => return error.SystemResources,
- .SRCH => return error.ProcessNotFound,
- else => unreachable,
- }
- }
-}
-
pub const INotifyInitError = error{
ProcessFdQuotaExceeded,
SystemFdQuotaExceeded,