| author | |
| committer | |
| log | 3961fe3de9713e3e618551cd96873a7b3948a2b2 |
| tree | e070dcf7f04352f3068497e5ea7e804738f9c9e2 |
| parent | 2c6304efc798d8a3773ae126661902b3a3214854 |
3 files changed, 59 insertions(+), 58 deletions(-)
lib/std/Build/Watch.zig+4-4| ... | @@ -699,7 +699,7 @@ const Os = switch (builtin.os.tag) { | ... | @@ -699,7 +699,7 @@ const Os = switch (builtin.os.tag) { |
| 699 | .data = 0, | 699 | .data = 0, |
| 700 | .udata = gop.index, | 700 | .udata = gop.index, |
| 701 | }}; | 701 | }}; |
| 702 | _ = try posix.kevent(w.os.kq_fd, &changes, &.{}, null); | 702 | _ = try Io.Kqueue.kevent(w.os.kq_fd, &changes, &.{}, null); |
| 703 | assert(handles.len == gop.index); | 703 | assert(handles.len == gop.index); |
| 704 | try handles.append(gpa, .{ | 704 | try handles.append(gpa, .{ |
| 705 | .rs = .{}, | 705 | .rs = .{}, |
| ... | @@ -789,7 +789,7 @@ const Os = switch (builtin.os.tag) { | ... | @@ -789,7 +789,7 @@ const Os = switch (builtin.os.tag) { |
| 789 | }, | 789 | }, |
| 790 | }; | 790 | }; |
| 791 | const filtered_changes = if (i == handles.len - 1) changes[0..1] else &changes; | 791 | const filtered_changes = if (i == handles.len - 1) changes[0..1] else &changes; |
| 792 | _ = try posix.kevent(w.os.kq_fd, filtered_changes, &.{}, null); | 792 | _ = try Io.Kqueue.kevent(w.os.kq_fd, filtered_changes, &.{}, null); |
| 793 | if (path.sub_path.len != 0) posix.close(dir_fd); | 793 | if (path.sub_path.len != 0) posix.close(dir_fd); |
| 794 | 794 | ||
| 795 | w.dir_table.swapRemoveAt(i); | 795 | w.dir_table.swapRemoveAt(i); |
| ... | @@ -803,13 +803,13 @@ const Os = switch (builtin.os.tag) { | ... | @@ -803,13 +803,13 @@ const Os = switch (builtin.os.tag) { |
| 803 | fn wait(w: *Watch, gpa: Allocator, timeout: Timeout) !WaitResult { | 803 | fn wait(w: *Watch, gpa: Allocator, timeout: Timeout) !WaitResult { |
| 804 | var timespec_buffer: posix.timespec = undefined; | 804 | var timespec_buffer: posix.timespec = undefined; |
| 805 | var event_buffer: [100]posix.Kevent = undefined; | 805 | var event_buffer: [100]posix.Kevent = undefined; |
| 806 | var n = try posix.kevent(w.os.kq_fd, &.{}, &event_buffer, timeout.toTimespec(&timespec_buffer)); | 806 | var n = try Io.Kqueue.kevent(w.os.kq_fd, &.{}, &event_buffer, timeout.toTimespec(&timespec_buffer)); |
| 807 | if (n == 0) return .timeout; | 807 | if (n == 0) return .timeout; |
| 808 | const reaction_sets = w.os.handles.items(.rs); | 808 | const reaction_sets = w.os.handles.items(.rs); |
| 809 | var any_dirty = markDirtySteps(gpa, reaction_sets, event_buffer[0..n], false); | 809 | var any_dirty = markDirtySteps(gpa, reaction_sets, event_buffer[0..n], false); |
| 810 | timespec_buffer = .{ .sec = 0, .nsec = 0 }; | 810 | timespec_buffer = .{ .sec = 0, .nsec = 0 }; |
| 811 | while (n == event_buffer.len) { | 811 | while (n == event_buffer.len) { |
| 812 | n = try posix.kevent(w.os.kq_fd, &.{}, &event_buffer, &timespec_buffer); | 812 | n = try Io.Kqueue.kevent(w.os.kq_fd, &.{}, &event_buffer, &timespec_buffer); |
| 813 | if (n == 0) break; | 813 | if (n == 0) break; |
| 814 | any_dirty = markDirtySteps(gpa, reaction_sets, event_buffer[0..n], any_dirty); | 814 | any_dirty = markDirtySteps(gpa, reaction_sets, event_buffer[0..n], any_dirty); |
| 815 | } | 815 | } |
lib/std/Io/Kqueue.zig+55-6| ... | @@ -334,7 +334,10 @@ fn schedule(k: *Kqueue, thread: *Thread, ready_queue: Fiber.Queue) void { | ... | @@ -334,7 +334,10 @@ fn schedule(k: *Kqueue, thread: *Thread, ready_queue: Fiber.Queue) void { |
| 334 | }, | 334 | }, |
| 335 | }; | 335 | }; |
| 336 | // If an error occurs it only pessimises scheduling. | 336 | // If an error occurs it only pessimises scheduling. |
| 337 | _ = posix.kevent(idle_search_thread.kq_fd, &changes, &.{}, null) catch {}; | 337 | _ = kevent(idle_search_thread.kq_fd, &changes, &.{}, null) catch |err| { |
| 338 | // TODO handle EINTR for cancellation purposes | ||
| 339 | @panic(@errorName(err)); // TODO | ||
| 340 | }; | ||
| 338 | return; | 341 | return; |
| 339 | } | 342 | } |
| 340 | spawn_thread: { | 343 | spawn_thread: { |
| ... | @@ -429,9 +432,9 @@ fn idle(k: *Kqueue, thread: *Thread) void { | ... | @@ -429,9 +432,9 @@ fn idle(k: *Kqueue, thread: *Thread) void { |
| 429 | k.yield(ready_fiber, .nothing); | 432 | k.yield(ready_fiber, .nothing); |
| 430 | maybe_ready_fiber = null; | 433 | maybe_ready_fiber = null; |
| 431 | } | 434 | } |
| 432 | const n = posix.kevent(thread.kq_fd, &.{}, &events_buffer, null) catch |err| { | 435 | const n = kevent(thread.kq_fd, &.{}, &events_buffer, null) catch |err| { |
| 433 | // TODO handle EINTR for cancellation purposes | 436 | // TODO handle EINTR for cancellation purposes |
| 434 | @panic(@errorName(err)); | 437 | @panic(@errorName(err)); // TODO |
| 435 | }; | 438 | }; |
| 436 | var maybe_ready_queue: ?Fiber.Queue = null; | 439 | var maybe_ready_queue: ?Fiber.Queue = null; |
| 437 | for (events_buffer[0..n]) |event| switch (@as(Completion.UserData, @enumFromInt(event.udata))) { | 440 | for (events_buffer[0..n]) |event| switch (@as(Completion.UserData, @enumFromInt(event.udata))) { |
| ... | @@ -598,8 +601,9 @@ const SwitchMessage = struct { | ... | @@ -598,8 +601,9 @@ const SwitchMessage = struct { |
| 598 | .udata = @intFromEnum(Completion.UserData.exit), | 601 | .udata = @intFromEnum(Completion.UserData.exit), |
| 599 | }, | 602 | }, |
| 600 | }; | 603 | }; |
| 601 | _ = posix.kevent(each_thread.kq_fd, &changes, &.{}, null) catch |err| { | 604 | _ = kevent(each_thread.kq_fd, &changes, &.{}, null) catch |err| { |
| 602 | @panic(@errorName(err)); | 605 | // TODO handle EINTR for cancellation purposes |
| 606 | @panic(@errorName(err)); // TODO | ||
| 603 | }; | 607 | }; |
| 604 | }, | 608 | }, |
| 605 | } | 609 | } |
| ... | @@ -1538,7 +1542,8 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea | ... | @@ -1538,7 +1542,8 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea |
| 1538 | .udata = @intFromPtr(fiber), | 1542 | .udata = @intFromPtr(fiber), |
| 1539 | }, | 1543 | }, |
| 1540 | }; | 1544 | }; |
| 1541 | assert(0 == (posix.kevent(thread.kq_fd, &changes, &.{}, null) catch |err| { | 1545 | assert(0 == (kevent(thread.kq_fd, &changes, &.{}, null) catch |err| { |
| 1546 | // TODO handle EINTR for cancellation purposes | ||
| 1542 | @panic(@errorName(err)); // TODO | 1547 | @panic(@errorName(err)); // TODO |
| 1543 | })); | 1548 | })); |
| 1544 | } | 1549 | } |
| ... | @@ -1774,3 +1779,47 @@ const Condition = struct { | ... | @@ -1774,3 +1779,47 @@ const Condition = struct { |
| 1774 | wake: Io.Condition.Wake, | 1779 | wake: Io.Condition.Wake, |
| 1775 | }, | 1780 | }, |
| 1776 | }; | 1781 | }; |
| 1782 | |||
| 1783 | pub const KEventError = error{ | ||
| 1784 | /// The process does not have permission to register a filter. | ||
| 1785 | AccessDenied, | ||
| 1786 | /// The event could not be found to be modified or deleted. | ||
| 1787 | EventNotFound, | ||
| 1788 | /// No memory was available to register the event. | ||
| 1789 | SystemResources, | ||
| 1790 | /// The specified process to attach to does not exist. | ||
| 1791 | ProcessNotFound, | ||
| 1792 | /// changelist or eventlist had too many items on it. | ||
| 1793 | /// TODO remove this possibility | ||
| 1794 | Overflow, | ||
| 1795 | }; | ||
| 1796 | |||
| 1797 | pub fn kevent( | ||
| 1798 | kq: i32, | ||
| 1799 | changelist: []const posix.Kevent, | ||
| 1800 | eventlist: []posix.Kevent, | ||
| 1801 | timeout: ?*const posix.timespec, | ||
| 1802 | ) KEventError!usize { | ||
| 1803 | while (true) { | ||
| 1804 | const rc = posix.system.kevent( | ||
| 1805 | kq, | ||
| 1806 | changelist.ptr, | ||
| 1807 | std.math.cast(c_int, changelist.len) orelse return error.Overflow, | ||
| 1808 | eventlist.ptr, | ||
| 1809 | std.math.cast(c_int, eventlist.len) orelse return error.Overflow, | ||
| 1810 | timeout, | ||
| 1811 | ); | ||
| 1812 | switch (posix.errno(rc)) { | ||
| 1813 | .SUCCESS => return @intCast(rc), | ||
| 1814 | .ACCES => return error.AccessDenied, | ||
| 1815 | .FAULT => unreachable, // TODO use error.Unexpected for these | ||
| 1816 | .BADF => unreachable, // Always a race condition. | ||
| 1817 | .INTR => continue, // TODO handle cancelation | ||
| 1818 | .INVAL => unreachable, | ||
| 1819 | .NOENT => return error.EventNotFound, | ||
| 1820 | .NOMEM => return error.SystemResources, | ||
| 1821 | .SRCH => return error.ProcessNotFound, | ||
| 1822 | else => unreachable, | ||
| 1823 | } | ||
| 1824 | } | ||
| 1825 | } |
lib/std/posix.zig-48| ... | @@ -792,54 +792,6 @@ pub fn fstat(fd: fd_t) FStatError!Stat { | ... | @@ -792,54 +792,6 @@ pub fn fstat(fd: fd_t) FStatError!Stat { |
| 792 | } | 792 | } |
| 793 | } | 793 | } |
| 794 | 794 | ||
| 795 | pub const KEventError = error{ | ||
| 796 | /// The process does not have permission to register a filter. | ||
| 797 | AccessDenied, | ||
| 798 | |||
| 799 | /// The event could not be found to be modified or deleted. | ||
| 800 | EventNotFound, | ||
| 801 | |||
| 802 | /// No memory was available to register the event. | ||
| 803 | SystemResources, | ||
| 804 | |||
| 805 | /// The specified process to attach to does not exist. | ||
| 806 | ProcessNotFound, | ||
| 807 | |||
| 808 | /// changelist or eventlist had too many items on it. | ||
| 809 | /// TODO remove this possibility | ||
| 810 | Overflow, | ||
| 811 | }; | ||
| 812 | |||
| 813 | pub fn kevent( | ||
| 814 | kq: i32, | ||
| 815 | changelist: []const Kevent, | ||
| 816 | eventlist: []Kevent, | ||
| 817 | timeout: ?*const timespec, | ||
| 818 | ) KEventError!usize { | ||
| 819 | while (true) { | ||
| 820 | const rc = system.kevent( | ||
| 821 | kq, | ||
| 822 | changelist.ptr, | ||
| 823 | cast(c_int, changelist.len) orelse return error.Overflow, | ||
| 824 | eventlist.ptr, | ||
| 825 | cast(c_int, eventlist.len) orelse return error.Overflow, | ||
| 826 | timeout, | ||
| 827 | ); | ||
| 828 | switch (errno(rc)) { | ||
| 829 | .SUCCESS => return @intCast(rc), | ||
| 830 | .ACCES => return error.AccessDenied, | ||
| 831 | .FAULT => unreachable, | ||
| 832 | .BADF => unreachable, // Always a race condition. | ||
| 833 | .INTR => continue, | ||
| 834 | .INVAL => unreachable, | ||
| 835 | .NOENT => return error.EventNotFound, | ||
| 836 | .NOMEM => return error.SystemResources, | ||
| 837 | .SRCH => return error.ProcessNotFound, | ||
| 838 | else => unreachable, | ||
| 839 | } | ||
| 840 | } | ||
| 841 | } | ||
| 842 | |||
| 843 | pub const INotifyInitError = error{ | 795 | pub const INotifyInitError = error{ |
| 844 | ProcessFdQuotaExceeded, | 796 | ProcessFdQuotaExceeded, |
| 845 | SystemFdQuotaExceeded, | 797 | SystemFdQuotaExceeded, |