| ... | @@ -2695,7 +2695,10 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa | ... | @@ -2695,7 +2695,10 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa |
| 2695 | const op = ring[submit_head.index(len)]; | 2695 | const op = ring[submit_head.index(len)]; |
| 2696 | const operation = &operations[op]; | 2696 | const operation = &operations[op]; |
| 2697 | const metadata = &metadatas[op]; | 2697 | const metadata = &metadatas[op]; |
| 2698 | metadata.* = .{ .iosb = undefined, .pending = false }; | 2698 | metadata.* = .{ .iosb = .{ |
| | 2699 | .u = .{ .Status = .PENDING }, |
| | 2700 | .Information = 0, |
| | 2701 | }, .pending = false }; |
| 2699 | switch (operation.*) { | 2702 | switch (operation.*) { |
| 2700 | .noop => |*o| { | 2703 | .noop => |*o| { |
| 2701 | _ = o.status.unstarted; | 2704 | _ = o.status.unstarted; |
| ... | @@ -2704,15 +2707,13 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa | ... | @@ -2704,15 +2707,13 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa |
| 2704 | }, | 2707 | }, |
| 2705 | .file_read_streaming => |*o| { | 2708 | .file_read_streaming => |*o| { |
| 2706 | _ = o.status.unstarted; | 2709 | _ = o.status.unstarted; |
| 2707 | switch (try ntReadFile(o.file.handle, o.data, &metadata.iosb)) { | 2710 | try ntReadFile(o.file.handle, o.data, &metadata.iosb); |
| 2708 | .status => { | 2711 | if (@atomicLoad(windows.NTSTATUS, &metadata.iosb.u.Status, .acquire) == .PENDING) { |
| 2709 | o.status = .{ .result = ntReadFileResult(&metadata.iosb) }; | 2712 | o.status = .{ .pending = b }; |
| 2710 | submitComplete(ring, &complete_tail, op); | 2713 | metadata.pending = true; |
| 2711 | }, | 2714 | } else { |
| 2712 | .pending => { | 2715 | o.status = .{ .result = ntReadFileResult(&metadata.iosb) }; |
| 2713 | o.status = .{ .pending = b }; | 2716 | submitComplete(ring, &complete_tail, op); |
| 2714 | metadata.pending = true; | | |
| 2715 | }, | | |
| 2716 | } | 2717 | } |
| 2717 | }, | 2718 | }, |
| 2718 | } | 2719 | } |
| ... | @@ -8680,44 +8681,36 @@ fn fileReadStreamingPosix(file: File, data: []const []u8) File.ReadStreamingErro | ... | @@ -8680,44 +8681,36 @@ fn fileReadStreamingPosix(file: File, data: []const []u8) File.ReadStreamingErro |
| 8680 | } | 8681 | } |
| 8681 | | 8682 | |
| 8682 | fn fileReadStreamingWindows(file: File, data: []const []u8) File.ReadStreamingError!usize { | 8683 | fn fileReadStreamingWindows(file: File, data: []const []u8) File.ReadStreamingError!usize { |
| 8683 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; | 8684 | var io_status_block: windows.IO_STATUS_BLOCK = .{ |
| 8684 | if (ntReadFile(file.handle, data, &io_status_block)) |result| switch (result) { | 8685 | .u = .{ .Status = .PENDING }, |
| 8685 | .status => return ntReadFileResult(&io_status_block), | 8686 | .Information = 0, |
| 8686 | .pending => { | 8687 | }; |
| 8687 | // Once we get here we received PENDING so we must not return from the | 8688 | try ntReadFile(file.handle, data, &io_status_block); |
| 8688 | // function until the operation completes. | 8689 | while (@atomicLoad(windows.NTSTATUS, &io_status_block.u.Status, .acquire) == .PENDING) { |
| 8689 | defer 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 |
| 8690 | waitForApcOrAlert(); | 8691 | // operation completes, thereby releasing reference to io_status_block. |
| 8691 | }; | 8692 | const alertable_syscall = AlertableSyscall.start() catch |err| switch (err) { |
| 8692 | | 8693 | error.Canceled => |e| { |
| 8693 | const alertable_syscall = AlertableSyscall.start() catch |err| switch (err) { | 8694 | _ = windows.ntdll.NtCancelIoFile(file.handle, &io_status_block); |
| 8694 | error.Canceled => |e| { | 8695 | while (@atomicLoad(windows.NTSTATUS, &io_status_block.u.Status, .acquire) == .PENDING) { |
| 8695 | _ = windows.ntdll.NtCancelIoFile(file.handle, &io_status_block); | 8696 | waitForApcOrAlert(); |
| 8696 | return e; | 8697 | } |
| 8697 | }, | 8698 | return e; |
| 8698 | }; | 8699 | }, |
| 8699 | waitForApcOrAlert(); | 8700 | }; |
| 8700 | while (@atomicLoad(windows.NTSTATUS, &io_status_block.u.Status, .acquire) == .PENDING) { | 8701 | waitForApcOrAlert(); |
| 8701 | alertable_syscall.checkCancel() catch |err| switch (err) { | 8702 | alertable_syscall.finish(); |
| 8702 | error.Canceled => |e| { | 8703 | } |
| 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; | | |
| 8712 | return ntReadFileResult(&io_status_block); | 8704 | return ntReadFileResult(&io_status_block); |
| 8713 | } | 8705 | } |
| 8714 | | 8706 | |
| 8715 | fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize { | 8707 | fn ntReadFileResult(io_status_block: *const windows.IO_STATUS_BLOCK) !usize { |
| 8716 | switch (io_status_block.u.Status) { | 8708 | switch (io_status_block.u.Status) { |
| | 8709 | .PENDING => unreachable, |
| | 8710 | .CANCELLED => unreachable, |
| 8717 | .SUCCESS => return io_status_block.Information, | 8711 | .SUCCESS => return io_status_block.Information, |
| 8718 | .END_OF_FILE => return error.EndOfStream, | 8712 | .END_OF_FILE => return error.EndOfStream, |
| 8719 | .PIPE_BROKEN => return error.EndOfStream, | 8713 | .PIPE_BROKEN => return error.EndOfStream, |
| 8720 | .PENDING => unreachable, | | |
| 8721 | .INVALID_DEVICE_REQUEST => return error.IsDir, | 8714 | .INVALID_DEVICE_REQUEST => return error.IsDir, |
| 8722 | .LOCK_NOT_GRANTED => return error.LockViolation, | 8715 | .LOCK_NOT_GRANTED => return error.LockViolation, |
| 8723 | .ACCESS_DENIED => return error.AccessDenied, | 8716 | .ACCESS_DENIED => return error.AccessDenied, |
| ... | @@ -8725,50 +8718,42 @@ fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize { | ... | @@ -8725,50 +8718,42 @@ fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize { |
| 8725 | } | 8718 | } |
| 8726 | } | 8719 | } |
| 8727 | | 8720 | |
| 8728 | fn ntReadFile(handle: windows.HANDLE, data: []const []u8, iosb: *windows.IO_STATUS_BLOCK) Io.Cancelable!enum { status, pending } { | 8721 | fn ntReadFile(handle: windows.HANDLE, data: []const []u8, iosb: *windows.IO_STATUS_BLOCK) Io.Cancelable!void { |
| 8729 | var index: usize = 0; | 8722 | var index: usize = 0; |
| 8730 | while (index < data.len and data[index].len == 0) index += 1; | 8723 | while (index < data.len and data[index].len == 0) index += 1; |
| 8731 | if (index == data.len) { | 8724 | if (index == data.len) { |
| 8732 | iosb.u.Status = .SUCCESS; | 8725 | iosb.u.Status = .SUCCESS; |
| 8733 | iosb.Information = 0; | 8726 | iosb.Information = 0; |
| 8734 | return .status; | 8727 | return; |
| 8735 | } | 8728 | } |
| 8736 | const buffer = data[index]; | 8729 | const buffer = data[index]; |
| 8737 | | 8730 | |
| 8738 | const syscall: Syscall = try .start(); | 8731 | const syscall: Syscall = try .start(); |
| 8739 | while (true) { | 8732 | while (true) switch (windows.ntdll.NtReadFile( |
| 8740 | iosb.u.Status = .PENDING; | 8733 | handle, |
| 8741 | switch (windows.ntdll.NtReadFile( | 8734 | null, // event |
| 8742 | handle, | 8735 | noopApc, // apc callback |
| 8743 | null, // event | 8736 | null, // apc context |
| 8744 | noopApc, // apc callback | 8737 | iosb, |
| 8745 | null, // apc context | 8738 | buffer.ptr, |
| 8746 | iosb, | 8739 | @min(std.math.maxInt(u32), buffer.len), |
| 8747 | buffer.ptr, | 8740 | null, // byte offset |
| 8748 | @min(std.math.maxInt(u32), buffer.len), | 8741 | null, // key |
| 8749 | null, // byte offset | 8742 | )) { |
| 8750 | null, // key | 8743 | .PENDING => { |
| 8751 | )) { | 8744 | syscall.finish(); |
| 8752 | .PENDING => { | 8745 | return; |
| 8753 | syscall.finish(); | 8746 | }, |
| 8754 | return .pending; | 8747 | .CANCELLED => { |
| 8755 | }, | 8748 | try syscall.checkCancel(); |
| 8756 | .SUCCESS => { | 8749 | continue; |
| 8757 | syscall.finish(); | 8750 | }, |
| 8758 | iosb.u.Status = .SUCCESS; | 8751 | else => |status| { |
| 8759 | return .status; | 8752 | syscall.finish(); |
| 8760 | }, | 8753 | iosb.u.Status = status; |
| 8761 | .CANCELLED => { | 8754 | return; |
| 8762 | try syscall.checkCancel(); | 8755 | }, |
| 8763 | continue; | 8756 | }; |
| 8764 | }, | | |
| 8765 | else => |status| { | | |
| 8766 | syscall.finish(); | | |
| 8767 | iosb.u.Status = status; | | |
| 8768 | return .status; | | |
| 8769 | }, | | |
| 8770 | } | | |
| 8771 | } | | |
| 8772 | } | 8757 | } |
| 8773 | | 8758 | |
| 8774 | fn fileReadPositionalPosix(file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize { | 8759 | fn fileReadPositionalPosix(file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize { |