| ... | ... | @@ -109,30 +109,28 @@ pub async fn pwriteWindows(loop: *Loop, fd: os.FileHandle, data: []const u8, off |
| 109 | 109 | .base = Loop.ResumeNode{ |
| 110 | 110 | .id = Loop.ResumeNode.Id.Basic, |
| 111 | 111 | .handle = @handle(), |
| 112 | .overlapped = windows.OVERLAPPED{ |
| 113 | .Internal = 0, |
| 114 | .InternalHigh = 0, |
| 115 | .Offset = @truncate(u32, offset), |
| 116 | .OffsetHigh = @truncate(u32, offset >> 32), |
| 117 | .hEvent = null, |
| 118 | }, |
| 112 | 119 | }, |
| 113 | 120 | }; |
| 114 | | const completion_key = @ptrToInt(&resume_node.base); |
| 115 | | // TODO support concurrent async ops on the file handle |
| 116 | | // we can do this by ignoring completion key and using @fieldParentPtr with the *Overlapped |
| 117 | | _ = try os.windowsCreateIoCompletionPort(fd, loop.os_data.io_port, completion_key, undefined); |
| 118 | | var overlapped = windows.OVERLAPPED{ |
| 119 | | .Internal = 0, |
| 120 | | .InternalHigh = 0, |
| 121 | | .Offset = @truncate(u32, offset), |
| 122 | | .OffsetHigh = @truncate(u32, offset >> 32), |
| 123 | | .hEvent = null, |
| 124 | | }; |
| 121 | // TODO only call create io completion port once per fd |
| 122 | _ = try os.windowsCreateIoCompletionPort(fd, loop.os_data.io_port, undefined, undefined); |
| 125 | 123 | loop.beginOneEvent(); |
| 126 | 124 | errdefer loop.finishOneEvent(); |
| 127 | 125 | |
| 128 | 126 | errdefer { |
| 129 | | _ = windows.CancelIoEx(fd, &overlapped); |
| 127 | _ = windows.CancelIoEx(fd, &resume_node.base.overlapped); |
| 130 | 128 | } |
| 131 | 129 | suspend { |
| 132 | | _ = windows.WriteFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &overlapped); |
| 130 | _ = windows.WriteFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped); |
| 133 | 131 | } |
| 134 | 132 | var bytes_transferred: windows.DWORD = undefined; |
| 135 | | if (windows.GetOverlappedResult(fd, &overlapped, &bytes_transferred, windows.FALSE) == 0) { |
| 133 | if (windows.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) { |
| 136 | 134 | const err = windows.GetLastError(); |
| 137 | 135 | return switch (err) { |
| 138 | 136 | windows.ERROR.IO_PENDING => unreachable, |
| ... | ... | @@ -243,30 +241,28 @@ pub async fn preadWindows(loop: *Loop, fd: os.FileHandle, data: []u8, offset: u6 |
| 243 | 241 | .base = Loop.ResumeNode{ |
| 244 | 242 | .id = Loop.ResumeNode.Id.Basic, |
| 245 | 243 | .handle = @handle(), |
| 244 | .overlapped = windows.OVERLAPPED{ |
| 245 | .Internal = 0, |
| 246 | .InternalHigh = 0, |
| 247 | .Offset = @truncate(u32, offset), |
| 248 | .OffsetHigh = @truncate(u32, offset >> 32), |
| 249 | .hEvent = null, |
| 250 | }, |
| 246 | 251 | }, |
| 247 | 252 | }; |
| 248 | | const completion_key = @ptrToInt(&resume_node.base); |
| 249 | | // TODO support concurrent async ops on the file handle |
| 250 | | // we can do this by ignoring completion key and using @fieldParentPtr with the *Overlapped |
| 251 | | _ = try os.windowsCreateIoCompletionPort(fd, loop.os_data.io_port, completion_key, undefined); |
| 252 | | var overlapped = windows.OVERLAPPED{ |
| 253 | | .Internal = 0, |
| 254 | | .InternalHigh = 0, |
| 255 | | .Offset = @truncate(u32, offset), |
| 256 | | .OffsetHigh = @truncate(u32, offset >> 32), |
| 257 | | .hEvent = null, |
| 258 | | }; |
| 253 | // TODO only call create io completion port once per fd |
| 254 | _ = try os.windowsCreateIoCompletionPort(fd, loop.os_data.io_port, undefined, undefined); |
| 259 | 255 | loop.beginOneEvent(); |
| 260 | 256 | errdefer loop.finishOneEvent(); |
| 261 | 257 | |
| 262 | 258 | errdefer { |
| 263 | | _ = windows.CancelIoEx(fd, &overlapped); |
| 259 | _ = windows.CancelIoEx(fd, &resume_node.base.overlapped); |
| 264 | 260 | } |
| 265 | 261 | suspend { |
| 266 | | _ = windows.ReadFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &overlapped); |
| 262 | _ = windows.ReadFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped); |
| 267 | 263 | } |
| 268 | 264 | var bytes_transferred: windows.DWORD = undefined; |
| 269 | | if (windows.GetOverlappedResult(fd, &overlapped, &bytes_transferred, windows.FALSE) == 0) { |
| 265 | if (windows.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) { |
| 270 | 266 | const err = windows.GetLastError(); |
| 271 | 267 | return switch (err) { |
| 272 | 268 | windows.ERROR.IO_PENDING => unreachable, |
| ... | ... | @@ -1074,23 +1070,22 @@ pub fn Watch(comptime V: type) type { |
| 1074 | 1070 | .base = Loop.ResumeNode{ |
| 1075 | 1071 | .id = Loop.ResumeNode.Id.Basic, |
| 1076 | 1072 | .handle = @handle(), |
| 1073 | .overlapped = windows.OVERLAPPED{ |
| 1074 | .Internal = 0, |
| 1075 | .InternalHigh = 0, |
| 1076 | .Offset = 0, |
| 1077 | .OffsetHigh = 0, |
| 1078 | .hEvent = null, |
| 1079 | }, |
| 1077 | 1080 | }, |
| 1078 | 1081 | }; |
| 1079 | | const completion_key = @ptrToInt(&resume_node.base); |
| 1080 | | var overlapped = windows.OVERLAPPED{ |
| 1081 | | .Internal = 0, |
| 1082 | | .InternalHigh = 0, |
| 1083 | | .Offset = 0, |
| 1084 | | .OffsetHigh = 0, |
| 1085 | | .hEvent = null, |
| 1086 | | }; |
| 1087 | 1082 | var event_buf: [4096]u8 align(@alignOf(windows.FILE_NOTIFY_INFORMATION)) = undefined; |
| 1088 | 1083 | |
| 1089 | 1084 | // TODO handle this error not in the channel but in the setup |
| 1090 | 1085 | _ = os.windowsCreateIoCompletionPort( |
| 1091 | 1086 | dir_handle, |
| 1092 | 1087 | self.channel.loop.os_data.io_port, |
| 1093 | | completion_key, |
| 1088 | undefined, |
| 1094 | 1089 | undefined, |
| 1095 | 1090 | ) catch |err| { |
| 1096 | 1091 | await (async self.channel.put(err) catch unreachable); |
| ... | ... | @@ -1103,7 +1098,7 @@ pub fn Watch(comptime V: type) type { |
| 1103 | 1098 | self.channel.loop.beginOneEvent(); |
| 1104 | 1099 | errdefer self.channel.loop.finishOneEvent(); |
| 1105 | 1100 | errdefer { |
| 1106 | | _ = windows.CancelIoEx(dir_handle, &overlapped); |
| 1101 | _ = windows.CancelIoEx(dir_handle, &resume_node.base.overlapped); |
| 1107 | 1102 | } |
| 1108 | 1103 | suspend { |
| 1109 | 1104 | _ = windows.ReadDirectoryChangesW( |
| ... | ... | @@ -1116,13 +1111,13 @@ pub fn Watch(comptime V: type) type { |
| 1116 | 1111 | windows.FILE_NOTIFY_CHANGE_LAST_WRITE | windows.FILE_NOTIFY_CHANGE_LAST_ACCESS | |
| 1117 | 1112 | windows.FILE_NOTIFY_CHANGE_CREATION | windows.FILE_NOTIFY_CHANGE_SECURITY, |
| 1118 | 1113 | null, // number of bytes transferred (unused for async) |
| 1119 | | &overlapped, |
| 1114 | &resume_node.base.overlapped, |
| 1120 | 1115 | null, // completion routine - unused because we use IOCP |
| 1121 | 1116 | ); |
| 1122 | 1117 | } |
| 1123 | 1118 | } |
| 1124 | 1119 | var bytes_transferred: windows.DWORD = undefined; |
| 1125 | | if (windows.GetOverlappedResult(dir_handle, &overlapped, &bytes_transferred, windows.FALSE) == 0) { |
| 1120 | if (windows.GetOverlappedResult(dir_handle, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) { |
| 1126 | 1121 | const errno = windows.GetLastError(); |
| 1127 | 1122 | const err = switch (errno) { |
| 1128 | 1123 | else => os.unexpectedErrorWindows(errno), |