mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 02:24:33 +01:00
std.Io.Threaded: move the NtDelayExecution later in batchWait
also guard against receiving SUCCESS with 0 byte read ms docs say that pipes can do this if there is a 0 byte write
This commit is contained in:
parent
2fb224cb84
commit
fdf1ee973e
2 changed files with 29 additions and 16 deletions
|
|
@ -2705,18 +2705,6 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa
|
|||
var delay_interval: windows.LARGE_INTEGER = timeoutToWindowsInterval(timeout);
|
||||
|
||||
while (true) {
|
||||
const alertable_syscall = try AlertableSyscall.start();
|
||||
const delay_rc = windows.ntdll.NtDelayExecution(windows.TRUE, &delay_interval);
|
||||
alertable_syscall.finish();
|
||||
switch (delay_rc) {
|
||||
.SUCCESS => {
|
||||
// The thread woke due to the timeout. Although spurious
|
||||
// timeouts are OK, when no deadline is passed we must not
|
||||
// return `error.Timeout`.
|
||||
if (timeout != .none) return error.Timeout;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
var any_done = false;
|
||||
var any_pending = false;
|
||||
for (metadatas, 0..) |*metadata, op_usize| {
|
||||
|
|
@ -2738,6 +2726,18 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa
|
|||
}
|
||||
if (any_done) return;
|
||||
if (!any_pending) return;
|
||||
const alertable_syscall = try AlertableSyscall.start();
|
||||
const delay_rc = windows.ntdll.NtDelayExecution(windows.TRUE, &delay_interval);
|
||||
alertable_syscall.finish();
|
||||
switch (delay_rc) {
|
||||
.SUCCESS => {
|
||||
// The thread woke due to the timeout. Although spurious
|
||||
// timeouts are OK, when no deadline is passed we must not
|
||||
// return `error.Timeout`.
|
||||
if (timeout != .none) return error.Timeout;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8707,7 +8707,11 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us
|
|||
|
||||
fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize {
|
||||
switch (io_status_block.u.Status) {
|
||||
.SUCCESS, .END_OF_FILE, .PIPE_BROKEN => return io_status_block.Information,
|
||||
.SUCCESS => {
|
||||
assert(io_status_block.Information != 0);
|
||||
return io_status_block.Information;
|
||||
},
|
||||
.END_OF_FILE, .PIPE_BROKEN => return 0,
|
||||
.PENDING => unreachable,
|
||||
.INVALID_DEVICE_REQUEST => return error.IsDir,
|
||||
.LOCK_NOT_GRANTED => return error.LockViolation,
|
||||
|
|
@ -8744,6 +8748,17 @@ fn ntReadFile(handle: windows.HANDLE, data: []const []u8, iosb: *windows.IO_STAT
|
|||
syscall.finish();
|
||||
return .pending;
|
||||
},
|
||||
.SUCCESS => {
|
||||
// Only END_OF_FILE is the true end.
|
||||
if (iosb.Information == 0) {
|
||||
try syscall.checkCancel();
|
||||
continue;
|
||||
} else {
|
||||
syscall.finish();
|
||||
iosb.u.Status = .SUCCESS;
|
||||
return .status;
|
||||
}
|
||||
},
|
||||
.CANCELLED => {
|
||||
try syscall.checkCancel();
|
||||
continue;
|
||||
|
|
@ -9709,6 +9724,7 @@ fn writeFileStreamingWindows(
|
|||
handle: windows.HANDLE,
|
||||
bytes: []const u8,
|
||||
) File.Writer.Error!usize {
|
||||
assert(bytes.len != 0);
|
||||
var bytes_written: windows.DWORD = undefined;
|
||||
const adjusted_len = std.math.lossyCast(u32, bytes.len);
|
||||
const syscall: Syscall = try .start();
|
||||
|
|
|
|||
|
|
@ -188,9 +188,6 @@ pub extern "kernel32" fn PostQueuedCompletionStatus(
|
|||
lpOverlapped: ?*OVERLAPPED,
|
||||
) callconv(.winapi) BOOL;
|
||||
|
||||
// TODO:
|
||||
// GetOverlappedResultEx with bAlertable=false, which calls: GetStdHandle + WaitForSingleObjectEx.
|
||||
// Uses the SwitchBack system to run implementations for older programs; Do we care about this?
|
||||
pub extern "kernel32" fn GetOverlappedResult(
|
||||
hFile: HANDLE,
|
||||
lpOverlapped: *OVERLAPPED,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue