authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-10 13:19:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-10 13:19:07-04:00
log598e80957e6eccc13ade72ce2693dcd60934763d
tree7a98fc680877bbdf00c9431fd3f2cd922a1ce8b0
parent0df485d4dc764afc582b8ab684106b71d765d74f

windows: call CancelIo when canceling an fs watch


5 files changed, 18 insertions(+), 10 deletions(-)

src-self-hosted/compilation.zig+3-2
......@@ -545,14 +545,15 @@ pub const Compilation = struct {
545545 try comp.initTypes();
546546 defer comp.primitive_type_table.deinit();
547547
548 comp.main_loop_handle = async comp.mainLoop() catch unreachable;
548549 // Set this to indicate that initialization completed successfully.
549550 // from here on out we must not return an error.
550551 // This must occur before the first suspend/await.
551 comp.main_loop_handle = async comp.mainLoop() catch unreachable;
552552 out_comp.* = &comp;
553 // This suspend is resumed by destroy()
553554 suspend;
554
555555 // From here on is cleanup.
556
556557 await (async comp.deinit_group.wait() catch unreachable);
557558
558559 if (comp.tmp_dir.getOrNull()) |tmp_dir_result| if (tmp_dir_result.*) |tmp_dir| {
src-self-hosted/test.zig+1-1
......@@ -43,7 +43,7 @@ pub const TestContext = struct {
4343 .file_index = std.atomic.Int(usize).init(0),
4444 };
4545
46 try self.loop.initMultiThreaded(allocator);
46 try self.loop.initSingleThreaded(allocator);
4747 errdefer self.loop.deinit();
4848
4949 self.zig_compiler = try ZigCompiler.init(&self.loop);
std/event/fs.zig+3
......@@ -1117,6 +1117,9 @@ pub fn Watch(comptime V: type) type {
11171117 // TODO only 1 beginOneEvent for the whole coroutine
11181118 self.channel.loop.beginOneEvent();
11191119 errdefer self.channel.loop.finishOneEvent();
1120 errdefer {
1121 _ = windows.CancelIoEx(dir_handle, &overlapped);
1122 }
11201123 suspend {
11211124 _ = windows.ReadDirectoryChangesW(
11221125 dir_handle,
std/event/loop.zig+1
......@@ -686,6 +686,7 @@ pub const Loop = struct {
686686 switch (os.windowsGetQueuedCompletionStatus(self.os_data.io_port, &nbytes, &completion_key, &overlapped, windows.INFINITE)) {
687687 os.WindowsWaitResult.Aborted => return,
688688 os.WindowsWaitResult.Normal => {},
689 os.WindowsWaitResult.Cancelled => continue,
689690 }
690691 if (overlapped != null) break;
691692 }
std/os/windows/util.zig+10-7
......@@ -238,21 +238,24 @@ pub fn windowsPostQueuedCompletionStatus(completion_port: windows.HANDLE, bytes_
238238 }
239239}
240240
241pub const WindowsWaitResult = error{
241pub const WindowsWaitResult = enum{
242242 Normal,
243243 Aborted,
244 Cancelled,
244245};
245246
246247pub fn windowsGetQueuedCompletionStatus(completion_port: windows.HANDLE, bytes_transferred_count: *windows.DWORD, lpCompletionKey: *usize, lpOverlapped: *?*windows.OVERLAPPED, dwMilliseconds: windows.DWORD) WindowsWaitResult {
247248 if (windows.GetQueuedCompletionStatus(completion_port, bytes_transferred_count, lpCompletionKey, lpOverlapped, dwMilliseconds) == windows.FALSE) {
248 if (std.debug.runtime_safety) {
249 const err = windows.GetLastError();
250 if (err != windows.ERROR.ABANDONED_WAIT_0) {
251 std.debug.warn("err: {}\n", err);
249 const err = windows.GetLastError();
250 switch (err) {
251 windows.ERROR.ABANDONED_WAIT_0 => return WindowsWaitResult.Aborted,
252 windows.ERROR.OPERATION_ABORTED => return WindowsWaitResult.Cancelled,
253 else => {
254 if (std.debug.runtime_safety) {
255 std.debug.panic("unexpected error: {}\n", err);
256 }
252257 }
253 assert(err == windows.ERROR.ABANDONED_WAIT_0);
254258 }
255 return WindowsWaitResult.Aborted;
256259 }
257260 return WindowsWaitResult.Normal;
258261}