From 2c6304efc798d8a3773ae126661902b3a3214854 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 7 Jan 2026 14:56:13 -0800 Subject: [PATCH] std: move posix.kqueue to Io.Kqueue.createFileDescriptor --- lib/std/Build/Watch.zig | 4 +++- lib/std/Io/Kqueue.zig | 24 ++++++++++++++++++++++-- lib/std/posix.zig | 18 ------------------ 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/std/Build/Watch.zig b/lib/std/Build/Watch.zig index 0a0178a018b535f5d06c11275c87753a4a6aef2d..fb80d5d1d560116c41b9b710dddd033859b33b5c 100644 --- a/lib/std/Build/Watch.zig +++ b/lib/std/Build/Watch.zig @@ -1,5 +1,7 @@ const builtin = @import("builtin"); + const std = @import("../std.zig"); +const Io = std.Io; const Step = std.Build.Step; const Allocator = std.mem.Allocator; const assert = std.debug.assert; @@ -666,7 +668,7 @@ const Os = switch (builtin.os.tag) { .dir_table = .{}, .dir_count = 0, .os = .{ - .kq_fd = try posix.kqueue(), + .kq_fd = try Io.Kqueue.createFileDescriptor(), .handles = .empty, }, .generation = 0, diff --git a/lib/std/Io/Kqueue.zig b/lib/std/Io/Kqueue.zig index df9fa1dee68a9deaf03e5a7e074848b7554b7e45..c1230a1ce63b0c969489eed28fb0ffd5c6ea7d95 100644 --- a/lib/std/Io/Kqueue.zig +++ b/lib/std/Io/Kqueue.zig @@ -157,8 +157,11 @@ pub const InitOptions = struct { n_threads: ?usize = null, }; +pub const InitError = Allocator.Error || CreateFileDescriptorError; + pub fn init(k: *Kqueue, gpa: Allocator, options: InitOptions) !void { assert(options.n_threads != 0); + const n_threads = @max(1, options.n_threads orelse std.Thread.getCpuCount() catch 1); const threads_size = n_threads * @sizeOf(Thread); const idle_stack_end_offset = std.mem.alignForward(usize, threads_size + idle_stack_size, std.heap.page_size_max); @@ -204,7 +207,7 @@ pub fn init(k: *Kqueue, gpa: Allocator, options: InitOptions) !void { }, .current_context = &main_fiber.context, .ready_queue = null, - .kq_fd = try posix.kqueue(), + .kq_fd = try createFileDescriptor(), .idle_search_index = 1, .steal_ready_search_index = 1, .wait_queues = .empty, @@ -231,6 +234,23 @@ pub fn deinit(k: *Kqueue) void { k.* = undefined; } +pub const CreateFileDescriptorError = error{ + /// The per-process limit on the number of open file descriptors has been reached. + ProcessFdQuotaExceeded, + /// The system-wide limit on the total number of open files has been reached. + SystemFdQuotaExceeded, +} || Io.Unexpected; + +pub fn createFileDescriptor() CreateFileDescriptorError!posix.fd_t { + const rc = posix.system.kqueue(); + switch (posix.errno(rc)) { + .SUCCESS => return @intCast(rc), + .MFILE => return error.ProcessFdQuotaExceeded, + .NFILE => return error.SystemFdQuotaExceeded, + else => |err| return posix.unexpectedErrno(err), + } +} + fn findReadyFiber(k: *Kqueue, thread: *Thread) ?*Fiber { if (@atomicRmw(?*Fiber, &thread.ready_queue, .Xchg, Fiber.finished, .acquire)) |ready_fiber| { @atomicStore(?*Fiber, &thread.ready_queue, ready_fiber.queue_next, .release); @@ -334,7 +354,7 @@ fn schedule(k: *Kqueue, thread: *Thread, ready_queue: Fiber.Queue) void { .idle_context = undefined, .current_context = &new_thread.idle_context, .ready_queue = ready_queue.head, - .kq_fd = posix.kqueue() catch |err| { + .kq_fd = createFileDescriptor() catch |err| { @atomicStore(u32, &k.threads.reserved, new_thread_index, .release); // no more access to `thread` after giving up reservation std.log.warn("unable to create worker thread due to kqueue init failure: {t}", .{err}); diff --git a/lib/std/posix.zig b/lib/std/posix.zig index 331fa3b1e2aade5bf3b56c58009f8014c1e0b04f..603af9fb458246e7da35ff273addff7ba4b8bbca 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -792,24 +792,6 @@ pub fn fstat(fd: fd_t) FStatError!Stat { } } -pub const KQueueError = error{ - /// The per-process limit on the number of open file descriptors has been reached. - ProcessFdQuotaExceeded, - - /// The system-wide limit on the total number of open files has been reached. - SystemFdQuotaExceeded, -} || UnexpectedError; - -pub fn kqueue() KQueueError!i32 { - const rc = system.kqueue(); - switch (errno(rc)) { - .SUCCESS => return @intCast(rc), - .MFILE => return error.ProcessFdQuotaExceeded, - .NFILE => return error.SystemFdQuotaExceeded, - else => |err| return unexpectedErrno(err), - } -} - pub const KEventError = error{ /// The process does not have permission to register a filter. AccessDenied, -- 2.54.0