windows: call CancelIo when canceling an fs watch
This commit is contained in:
parent
0df485d4dc
commit
598e80957e
@ -545,14 +545,15 @@ pub const Compilation = struct {
|
||||
try comp.initTypes();
|
||||
defer comp.primitive_type_table.deinit();
|
||||
|
||||
comp.main_loop_handle = async comp.mainLoop() catch unreachable;
|
||||
// Set this to indicate that initialization completed successfully.
|
||||
// from here on out we must not return an error.
|
||||
// This must occur before the first suspend/await.
|
||||
comp.main_loop_handle = async comp.mainLoop() catch unreachable;
|
||||
out_comp.* = ∁
|
||||
// This suspend is resumed by destroy()
|
||||
suspend;
|
||||
|
||||
// From here on is cleanup.
|
||||
|
||||
await (async comp.deinit_group.wait() catch unreachable);
|
||||
|
||||
if (comp.tmp_dir.getOrNull()) |tmp_dir_result| if (tmp_dir_result.*) |tmp_dir| {
|
||||
|
@ -43,7 +43,7 @@ pub const TestContext = struct {
|
||||
.file_index = std.atomic.Int(usize).init(0),
|
||||
};
|
||||
|
||||
try self.loop.initMultiThreaded(allocator);
|
||||
try self.loop.initSingleThreaded(allocator);
|
||||
errdefer self.loop.deinit();
|
||||
|
||||
self.zig_compiler = try ZigCompiler.init(&self.loop);
|
||||
|
@ -1117,6 +1117,9 @@ pub fn Watch(comptime V: type) type {
|
||||
// TODO only 1 beginOneEvent for the whole coroutine
|
||||
self.channel.loop.beginOneEvent();
|
||||
errdefer self.channel.loop.finishOneEvent();
|
||||
errdefer {
|
||||
_ = windows.CancelIoEx(dir_handle, &overlapped);
|
||||
}
|
||||
suspend {
|
||||
_ = windows.ReadDirectoryChangesW(
|
||||
dir_handle,
|
||||
|
@ -686,6 +686,7 @@ pub const Loop = struct {
|
||||
switch (os.windowsGetQueuedCompletionStatus(self.os_data.io_port, &nbytes, &completion_key, &overlapped, windows.INFINITE)) {
|
||||
os.WindowsWaitResult.Aborted => return,
|
||||
os.WindowsWaitResult.Normal => {},
|
||||
os.WindowsWaitResult.Cancelled => continue,
|
||||
}
|
||||
if (overlapped != null) break;
|
||||
}
|
||||
|
@ -238,21 +238,24 @@ pub fn windowsPostQueuedCompletionStatus(completion_port: windows.HANDLE, bytes_
|
||||
}
|
||||
}
|
||||
|
||||
pub const WindowsWaitResult = error{
|
||||
pub const WindowsWaitResult = enum{
|
||||
Normal,
|
||||
Aborted,
|
||||
Cancelled,
|
||||
};
|
||||
|
||||
pub fn windowsGetQueuedCompletionStatus(completion_port: windows.HANDLE, bytes_transferred_count: *windows.DWORD, lpCompletionKey: *usize, lpOverlapped: *?*windows.OVERLAPPED, dwMilliseconds: windows.DWORD) WindowsWaitResult {
|
||||
if (windows.GetQueuedCompletionStatus(completion_port, bytes_transferred_count, lpCompletionKey, lpOverlapped, dwMilliseconds) == windows.FALSE) {
|
||||
if (std.debug.runtime_safety) {
|
||||
const err = windows.GetLastError();
|
||||
if (err != windows.ERROR.ABANDONED_WAIT_0) {
|
||||
std.debug.warn("err: {}\n", err);
|
||||
const err = windows.GetLastError();
|
||||
switch (err) {
|
||||
windows.ERROR.ABANDONED_WAIT_0 => return WindowsWaitResult.Aborted,
|
||||
windows.ERROR.OPERATION_ABORTED => return WindowsWaitResult.Cancelled,
|
||||
else => {
|
||||
if (std.debug.runtime_safety) {
|
||||
std.debug.panic("unexpected error: {}\n", err);
|
||||
}
|
||||
}
|
||||
assert(err == windows.ERROR.ABANDONED_WAIT_0);
|
||||
}
|
||||
return WindowsWaitResult.Aborted;
|
||||
}
|
||||
return WindowsWaitResult.Normal;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user