zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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:
Mlib/std/Build/Watch.zig | 8++++----
Mlib/std/Io/Kqueue.zig | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Mlib/std/posix.zig | 48------------------------------------------------
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(&timespec_buffer)); + var n = try Io.Kqueue.kevent(w.os.kq_fd, &.{}, &event_buffer, timeout.toTimespec(&timespec_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, &timespec_buffer); + n = try Io.Kqueue.kevent(w.os.kq_fd, &.{}, &event_buffer, &timespec_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,