authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-28 21:02:43-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-30 22:03:14-08:00
log4dd7fe90a2b541a44aafc3a9596445387a3aed49
tree3468c6d6f51d80b17e0b30db2bd2d635c3aff7a7
parent3320e6a1ae453d40dd78ff3abf6c8543bec2555d

std.Io.Threaded: compress ntReadFile logic

Just use the ntstatus field rather than an additional enum

1 files changed, 61 insertions(+), 76 deletions(-)

lib/std/Io/Threaded.zig+61-76
......@@ -2695,7 +2695,10 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa
26952695 const op = ring[submit_head.index(len)];
26962696 const operation = &operations[op];
26972697 const metadata = &metadatas[op];
2698 metadata.* = .{ .iosb = undefined, .pending = false };
2698 metadata.* = .{ .iosb = .{
2699 .u = .{ .Status = .PENDING },
2700 .Information = 0,
2701 }, .pending = false };
26992702 switch (operation.*) {
27002703 .noop => |*o| {
27012704 _ = o.status.unstarted;
......@@ -2704,15 +2707,13 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa
27042707 },
27052708 .file_read_streaming => |*o| {
27062709 _ = o.status.unstarted;
2707 switch (try ntReadFile(o.file.handle, o.data, &metadata.iosb)) {
2708 .status => {
2709 o.status = .{ .result = ntReadFileResult(&metadata.iosb) };
2710 submitComplete(ring, &complete_tail, op);
2711 },
2712 .pending => {
2713 o.status = .{ .pending = b };
2714 metadata.pending = true;
2715 },
2710 try ntReadFile(o.file.handle, o.data, &metadata.iosb);
2711 if (@atomicLoad(windows.NTSTATUS, &metadata.iosb.u.Status, .acquire) == .PENDING) {
2712 o.status = .{ .pending = b };
2713 metadata.pending = true;
2714 } else {
2715 o.status = .{ .result = ntReadFileResult(&metadata.iosb) };
2716 submitComplete(ring, &complete_tail, op);
27162717 }
27172718 },
27182719 }
......@@ -8680,44 +8681,36 @@ fn fileReadStreamingPosix(file: File, data: []const []u8) File.ReadStreamingErro
86808681}
86818682
86828683fn fileReadStreamingWindows(file: File, data: []const []u8) File.ReadStreamingError!usize {
8683 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
8684 if (ntReadFile(file.handle, data, &io_status_block)) |result| switch (result) {
8685 .status => return ntReadFileResult(&io_status_block),
8686 .pending => {
8687 // Once we get here we received PENDING so we must not return from the
8688 // function until the operation completes.
8689 defer while (@atomicLoad(windows.NTSTATUS, &io_status_block.u.Status, .acquire) == .PENDING) {
8690 waitForApcOrAlert();
8691 };
8692
8693 const alertable_syscall = AlertableSyscall.start() catch |err| switch (err) {
8694 error.Canceled => |e| {
8695 _ = windows.ntdll.NtCancelIoFile(file.handle, &io_status_block);
8696 return e;
8697 },
8698 };
8699 waitForApcOrAlert();
8700 while (@atomicLoad(windows.NTSTATUS, &io_status_block.u.Status, .acquire) == .PENDING) {
8701 alertable_syscall.checkCancel() catch |err| switch (err) {
8702 error.Canceled => |e| {
8703 _ = windows.ntdll.NtCancelIoFile(file.handle, &io_status_block);
8704 return e;
8705 },
8706 };
8707 waitForApcOrAlert();
8708 }
8709 alertable_syscall.finish();
8710 },
8711 } else |err| return err;
8684 var io_status_block: windows.IO_STATUS_BLOCK = .{
8685 .u = .{ .Status = .PENDING },
8686 .Information = 0,
8687 };
8688 try ntReadFile(file.handle, data, &io_status_block);
8689 while (@atomicLoad(windows.NTSTATUS, &io_status_block.u.Status, .acquire) == .PENDING) {
8690 // Once we get here we must not return from the function until the
8691 // operation completes, thereby releasing reference to io_status_block.
8692 const alertable_syscall = AlertableSyscall.start() catch |err| switch (err) {
8693 error.Canceled => |e| {
8694 _ = windows.ntdll.NtCancelIoFile(file.handle, &io_status_block);
8695 while (@atomicLoad(windows.NTSTATUS, &io_status_block.u.Status, .acquire) == .PENDING) {
8696 waitForApcOrAlert();
8697 }
8698 return e;
8699 },
8700 };
8701 waitForApcOrAlert();
8702 alertable_syscall.finish();
8703 }
87128704 return ntReadFileResult(&io_status_block);
87138705}
87148706
8715fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize {
8707fn ntReadFileResult(io_status_block: *const windows.IO_STATUS_BLOCK) !usize {
87168708 switch (io_status_block.u.Status) {
8709 .PENDING => unreachable,
8710 .CANCELLED => unreachable,
87178711 .SUCCESS => return io_status_block.Information,
87188712 .END_OF_FILE => return error.EndOfStream,
87198713 .PIPE_BROKEN => return error.EndOfStream,
8720 .PENDING => unreachable,
87218714 .INVALID_DEVICE_REQUEST => return error.IsDir,
87228715 .LOCK_NOT_GRANTED => return error.LockViolation,
87238716 .ACCESS_DENIED => return error.AccessDenied,
......@@ -8725,50 +8718,42 @@ fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize {
87258718 }
87268719}
87278720
8728fn ntReadFile(handle: windows.HANDLE, data: []const []u8, iosb: *windows.IO_STATUS_BLOCK) Io.Cancelable!enum { status, pending } {
8721fn ntReadFile(handle: windows.HANDLE, data: []const []u8, iosb: *windows.IO_STATUS_BLOCK) Io.Cancelable!void {
87298722 var index: usize = 0;
87308723 while (index < data.len and data[index].len == 0) index += 1;
87318724 if (index == data.len) {
87328725 iosb.u.Status = .SUCCESS;
87338726 iosb.Information = 0;
8734 return .status;
8727 return;
87358728 }
87368729 const buffer = data[index];
87378730
87388731 const syscall: Syscall = try .start();
8739 while (true) {
8740 iosb.u.Status = .PENDING;
8741 switch (windows.ntdll.NtReadFile(
8742 handle,
8743 null, // event
8744 noopApc, // apc callback
8745 null, // apc context
8746 iosb,
8747 buffer.ptr,
8748 @min(std.math.maxInt(u32), buffer.len),
8749 null, // byte offset
8750 null, // key
8751 )) {
8752 .PENDING => {
8753 syscall.finish();
8754 return .pending;
8755 },
8756 .SUCCESS => {
8757 syscall.finish();
8758 iosb.u.Status = .SUCCESS;
8759 return .status;
8760 },
8761 .CANCELLED => {
8762 try syscall.checkCancel();
8763 continue;
8764 },
8765 else => |status| {
8766 syscall.finish();
8767 iosb.u.Status = status;
8768 return .status;
8769 },
8770 }
8771 }
8732 while (true) switch (windows.ntdll.NtReadFile(
8733 handle,
8734 null, // event
8735 noopApc, // apc callback
8736 null, // apc context
8737 iosb,
8738 buffer.ptr,
8739 @min(std.math.maxInt(u32), buffer.len),
8740 null, // byte offset
8741 null, // key
8742 )) {
8743 .PENDING => {
8744 syscall.finish();
8745 return;
8746 },
8747 .CANCELLED => {
8748 try syscall.checkCancel();
8749 continue;
8750 },
8751 else => |status| {
8752 syscall.finish();
8753 iosb.u.Status = status;
8754 return;
8755 },
8756 };
87728757}
87738758
87748759fn fileReadPositionalPosix(file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize {