| ... | @@ -2705,18 +2705,6 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa | ... | @@ -2705,18 +2705,6 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa |
| 2705 | var delay_interval: windows.LARGE_INTEGER = timeoutToWindowsInterval(timeout); | 2705 | var delay_interval: windows.LARGE_INTEGER = timeoutToWindowsInterval(timeout); |
| 2706 | | 2706 | |
| 2707 | while (true) { | 2707 | while (true) { |
| 2708 | const alertable_syscall = try AlertableSyscall.start(); | | |
| 2709 | const delay_rc = windows.ntdll.NtDelayExecution(windows.TRUE, &delay_interval); | | |
| 2710 | alertable_syscall.finish(); | | |
| 2711 | switch (delay_rc) { | | |
| 2712 | .SUCCESS => { | | |
| 2713 | // The thread woke due to the timeout. Although spurious | | |
| 2714 | // timeouts are OK, when no deadline is passed we must not | | |
| 2715 | // return `error.Timeout`. | | |
| 2716 | if (timeout != .none) return error.Timeout; | | |
| 2717 | }, | | |
| 2718 | else => {}, | | |
| 2719 | } | | |
| 2720 | var any_done = false; | 2708 | var any_done = false; |
| 2721 | var any_pending = false; | 2709 | var any_pending = false; |
| 2722 | for (metadatas, 0..) |*metadata, op_usize| { | 2710 | for (metadatas, 0..) |*metadata, op_usize| { |
| ... | @@ -2738,6 +2726,18 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa | ... | @@ -2738,6 +2726,18 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa |
| 2738 | } | 2726 | } |
| 2739 | if (any_done) return; | 2727 | if (any_done) return; |
| 2740 | if (!any_pending) return; | 2728 | if (!any_pending) return; |
| | 2729 | const alertable_syscall = try AlertableSyscall.start(); |
| | 2730 | const delay_rc = windows.ntdll.NtDelayExecution(windows.TRUE, &delay_interval); |
| | 2731 | alertable_syscall.finish(); |
| | 2732 | switch (delay_rc) { |
| | 2733 | .SUCCESS => { |
| | 2734 | // The thread woke due to the timeout. Although spurious |
| | 2735 | // timeouts are OK, when no deadline is passed we must not |
| | 2736 | // return `error.Timeout`. |
| | 2737 | if (timeout != .none) return error.Timeout; |
| | 2738 | }, |
| | 2739 | else => {}, |
| | 2740 | } |
| 2741 | } | 2741 | } |
| 2742 | } | 2742 | } |
| 2743 | | 2743 | |
| ... | @@ -8707,7 +8707,11 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us | ... | @@ -8707,7 +8707,11 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us |
| 8707 | | 8707 | |
| 8708 | fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize { | 8708 | fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize { |
| 8709 | switch (io_status_block.u.Status) { | 8709 | switch (io_status_block.u.Status) { |
| 8710 | .SUCCESS, .END_OF_FILE, .PIPE_BROKEN => return io_status_block.Information, | 8710 | .SUCCESS => { |
| | 8711 | assert(io_status_block.Information != 0); |
| | 8712 | return io_status_block.Information; |
| | 8713 | }, |
| | 8714 | .END_OF_FILE, .PIPE_BROKEN => return 0, |
| 8711 | .PENDING => unreachable, | 8715 | .PENDING => unreachable, |
| 8712 | .INVALID_DEVICE_REQUEST => return error.IsDir, | 8716 | .INVALID_DEVICE_REQUEST => return error.IsDir, |
| 8713 | .LOCK_NOT_GRANTED => return error.LockViolation, | 8717 | .LOCK_NOT_GRANTED => return error.LockViolation, |
| ... | @@ -8744,6 +8748,17 @@ fn ntReadFile(handle: windows.HANDLE, data: []const []u8, iosb: *windows.IO_STAT | ... | @@ -8744,6 +8748,17 @@ fn ntReadFile(handle: windows.HANDLE, data: []const []u8, iosb: *windows.IO_STAT |
| 8744 | syscall.finish(); | 8748 | syscall.finish(); |
| 8745 | return .pending; | 8749 | return .pending; |
| 8746 | }, | 8750 | }, |
| | 8751 | .SUCCESS => { |
| | 8752 | // Only END_OF_FILE is the true end. |
| | 8753 | if (iosb.Information == 0) { |
| | 8754 | try syscall.checkCancel(); |
| | 8755 | continue; |
| | 8756 | } else { |
| | 8757 | syscall.finish(); |
| | 8758 | iosb.u.Status = .SUCCESS; |
| | 8759 | return .status; |
| | 8760 | } |
| | 8761 | }, |
| 8747 | .CANCELLED => { | 8762 | .CANCELLED => { |
| 8748 | try syscall.checkCancel(); | 8763 | try syscall.checkCancel(); |
| 8749 | continue; | 8764 | continue; |
| ... | @@ -9709,6 +9724,7 @@ fn writeFileStreamingWindows( | ... | @@ -9709,6 +9724,7 @@ fn writeFileStreamingWindows( |
| 9709 | handle: windows.HANDLE, | 9724 | handle: windows.HANDLE, |
| 9710 | bytes: []const u8, | 9725 | bytes: []const u8, |
| 9711 | ) File.Writer.Error!usize { | 9726 | ) File.Writer.Error!usize { |
| | 9727 | assert(bytes.len != 0); |
| 9712 | var bytes_written: windows.DWORD = undefined; | 9728 | var bytes_written: windows.DWORD = undefined; |
| 9713 | const adjusted_len = std.math.lossyCast(u32, bytes.len); | 9729 | const adjusted_len = std.math.lossyCast(u32, bytes.len); |
| 9714 | const syscall: Syscall = try .start(); | 9730 | const syscall: Syscall = try .start(); |