diff --git a/src-self-hosted/compilation.zig b/src-self-hosted/compilation.zig index be54a2db76..ee9ff4f4a1 100644 --- a/src-self-hosted/compilation.zig +++ b/src-self-hosted/compilation.zig @@ -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| { diff --git a/src-self-hosted/test.zig b/src-self-hosted/test.zig index 572215e489..3582bbcf81 100644 --- a/src-self-hosted/test.zig +++ b/src-self-hosted/test.zig @@ -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); diff --git a/std/event/fs.zig b/std/event/fs.zig index 30b897ad6e..00f45f2af5 100644 --- a/std/event/fs.zig +++ b/std/event/fs.zig @@ -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, diff --git a/std/event/loop.zig b/std/event/loop.zig index bf96859fe7..733112549d 100644 --- a/std/event/loop.zig +++ b/std/event/loop.zig @@ -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; } diff --git a/std/os/windows/util.zig b/std/os/windows/util.zig index 9e13655f7f..2f9f4f2c72 100644 --- a/std/os/windows/util.zig +++ b/std/os/windows/util.zig @@ -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; }