| ... | @@ -339,7 +339,8 @@ const Group = struct { | ... | @@ -339,7 +339,8 @@ const Group = struct { |
| 339 | .canceled => true, | 339 | .canceled => true, |
| 340 | .parked => unreachable, | 340 | .parked => unreachable, |
| 341 | .blocked => unreachable, | 341 | .blocked => unreachable, |
| 342 | .blocked_windows_dns => unreachable, | 342 | .blocked_alertable => unreachable, |
| | 343 | .blocked_alertable_canceling => unreachable, |
| 343 | .blocked_canceling => unreachable, | 344 | .blocked_canceling => unreachable, |
| 344 | }; | 345 | }; |
| 345 | if (result) { | 346 | if (result) { |
| ... | @@ -542,7 +543,8 @@ const Future = struct { | ... | @@ -542,7 +543,8 @@ const Future = struct { |
| 542 | .canceled => true, | 543 | .canceled => true, |
| 543 | .parked => unreachable, | 544 | .parked => unreachable, |
| 544 | .blocked => unreachable, | 545 | .blocked => unreachable, |
| 545 | .blocked_windows_dns => unreachable, | 546 | .blocked_alertable => unreachable, |
| | 547 | .blocked_alertable_canceling => unreachable, |
| 546 | .blocked_canceling => unreachable, | 548 | .blocked_canceling => unreachable, |
| 547 | }; | 549 | }; |
| 548 | thread.status.store(.{ .cancelation = .none, .awaitable = .null }, .monotonic); | 550 | thread.status.store(.{ .cancelation = .none, .awaitable = .null }, .monotonic); |
| ... | @@ -650,9 +652,11 @@ const Thread = struct { | ... | @@ -650,9 +652,11 @@ const Thread = struct { |
| 650 | /// To request cancelation, set the status to `.blocked_canceling` and repeatedly interrupt the system call until the status changes. | 652 | /// To request cancelation, set the status to `.blocked_canceling` and repeatedly interrupt the system call until the status changes. |
| 651 | blocked = 0b011, | 653 | blocked = 0b011, |
| 652 | | 654 | |
| 653 | /// Windows-only: the thread is blocked in a call to `GetAddrInfoExW`. | 655 | /// Windows-only: the thread is blocked in an alertable wait via |
| 654 | /// To request cancelation, set the status to `.canceling` and call `GetAddrInfoExCancel`. | 656 | /// `NtDelayExecution`. To request cancelation, set the status to |
| 655 | blocked_windows_dns = 0b010, | 657 | /// `blocked_alertable_canceling` and repeatedly alert the thread |
| | 658 | /// until the status changes. |
| | 659 | blocked_alertable = 0b010, |
| 656 | | 660 | |
| 657 | /// The thread has an outstanding cancelation request but is not in a cancelable operation. | 661 | /// The thread has an outstanding cancelation request but is not in a cancelable operation. |
| 658 | /// When it acknowledges the cancelation, it will set the status to `.canceled`. | 662 | /// When it acknowledges the cancelation, it will set the status to `.canceled`. |
| ... | @@ -663,9 +667,16 @@ const Thread = struct { | ... | @@ -663,9 +667,16 @@ const Thread = struct { |
| 663 | /// will not change for the remainder of this task's execution. | 667 | /// will not change for the remainder of this task's execution. |
| 664 | canceled = 0b111, | 668 | canceled = 0b111, |
| 665 | | 669 | |
| 666 | /// The thread is blocked in a cancelable system call, and is being canceled. The thread which triggered the cancelation will send signals to this thread | 670 | /// The thread is blocked in a cancelable system call, and is being |
| 667 | /// until its status changes. | 671 | /// canceled. The thread which triggered the cancelation will send |
| | 672 | /// signals to this thread until its status changes. |
| 668 | blocked_canceling = 0b101, | 673 | blocked_canceling = 0b101, |
| | 674 | |
| | 675 | /// Windows-only: the thread is blocked in an alertable wait via |
| | 676 | /// `NtDelayExecution`, and is being canceled. The thread which |
| | 677 | /// triggered the cancelation will send signals to this thread |
| | 678 | /// until its status changes. |
| | 679 | blocked_alertable_canceling = 0b100, |
| 669 | }, | 680 | }, |
| 670 | | 681 | |
| 671 | /// We cannot turn this value back into a pointer. Instead, it exists so that a task can be | 682 | /// We cannot turn this value back into a pointer. Instead, it exists so that a task can be |
| ... | @@ -694,7 +705,8 @@ const Thread = struct { | ... | @@ -694,7 +705,8 @@ const Thread = struct { |
| 694 | switch (status.cancelation) { | 705 | switch (status.cancelation) { |
| 695 | .parked => unreachable, | 706 | .parked => unreachable, |
| 696 | .blocked => unreachable, | 707 | .blocked => unreachable, |
| 697 | .blocked_windows_dns => unreachable, | 708 | .blocked_alertable => unreachable, |
| | 709 | .blocked_alertable_canceling => unreachable, |
| 698 | .blocked_canceling => unreachable, | 710 | .blocked_canceling => unreachable, |
| 699 | .none, .canceled => {}, | 711 | .none, .canceled => {}, |
| 700 | .canceling => { | 712 | .canceling => { |
| ... | @@ -1007,19 +1019,14 @@ const Thread = struct { | ... | @@ -1007,19 +1019,14 @@ const Thread = struct { |
| 1007 | .monotonic, | 1019 | .monotonic, |
| 1008 | ) orelse return true, | 1020 | ) orelse return true, |
| 1009 | | 1021 | |
| 1010 | .blocked_windows_dns => thread.status.cmpxchgWeak( | 1022 | .blocked_alertable => thread.status.cmpxchgWeak( |
| 1011 | .{ .cancelation = .blocked_windows_dns, .awaitable = awaitable }, | 1023 | .{ .cancelation = .blocked_alertable, .awaitable = awaitable }, |
| 1012 | .{ .cancelation = .canceling, .awaitable = awaitable }, | 1024 | .{ .cancelation = .blocked_alertable_canceling, .awaitable = awaitable }, |
| 1013 | .monotonic, | 1025 | .monotonic, |
| 1014 | .monotonic, | 1026 | .monotonic, |
| 1015 | ) orelse { | 1027 | ) orelse { |
| 1016 | if (builtin.target.os.tag != .windows) unreachable; | 1028 | if (!is_windows) unreachable; |
| 1017 | if (true) { | 1029 | return true; |
| 1018 | // TODO: cancel Windows DNS queries. This code path is currently impossible | | |
| 1019 | // as `netLookupFallible` doesn't actually use `.blocked_windows_dns` yet. | | |
| 1020 | unreachable; | | |
| 1021 | } | | |
| 1022 | return false; | | |
| 1023 | }, | 1030 | }, |
| 1024 | | 1031 | |
| 1025 | .canceling, .canceled => { | 1032 | .canceling, .canceled => { |
| ... | @@ -1029,7 +1036,8 @@ const Thread = struct { | ... | @@ -1029,7 +1036,8 @@ const Thread = struct { |
| 1029 | return false; | 1036 | return false; |
| 1030 | }, | 1037 | }, |
| 1031 | | 1038 | |
| 1032 | .blocked_canceling => unreachable, | 1039 | .blocked_canceling => unreachable, // `awaitable` has not been canceled before now |
| | 1040 | .blocked_alertable_canceling => unreachable, // `awaitable` has not been canceled before now |
| 1033 | }; | 1041 | }; |
| 1034 | } | 1042 | } |
| 1035 | } | 1043 | } |
| ... | @@ -1044,40 +1052,59 @@ const Thread = struct { | ... | @@ -1044,40 +1052,59 @@ const Thread = struct { |
| 1044 | /// `Group.waitForCancelWithSignaling`: they use exponential backoff starting at a 1us delay and | 1052 | /// `Group.waitForCancelWithSignaling`: they use exponential backoff starting at a 1us delay and |
| 1045 | /// doubling each call. In practice, it is rare to send more than one signal. | 1053 | /// doubling each call. In practice, it is rare to send more than one signal. |
| 1046 | fn signalCanceledSyscall(thread: *Thread, t: *Threaded, awaitable: AwaitableId) bool { | 1054 | fn signalCanceledSyscall(thread: *Thread, t: *Threaded, awaitable: AwaitableId) bool { |
| 1047 | const bad_status: Status = .{ .cancelation = .blocked_canceling, .awaitable = awaitable }; | 1055 | const status = thread.status.load(.monotonic); |
| 1048 | if (thread.status.load(.monotonic) != bad_status) return false; | 1056 | if (status.awaitable != awaitable) { |
| | 1057 | // The thread has moved on and is working on something totally different. |
| | 1058 | return false; |
| | 1059 | } |
| 1049 | | 1060 | |
| 1050 | // The thread ID and/or handle can be read non-atomically because they never change and were | 1061 | // The thread ID and/or handle can be read non-atomically because they never change and were |
| 1051 | // released by the store that made `thread` available to us. | 1062 | // released by the store that made `thread` available to us. |
| 1052 | | 1063 | |
| 1053 | if (std.Thread.use_pthreads) { | 1064 | switch (status.cancelation) { |
| 1054 | return switch (std.c.pthread_kill(thread.handle, .IO)) { | 1065 | .blocked_canceling => if (std.Thread.use_pthreads) { |
| 1055 | 0 => true, | 1066 | return switch (std.c.pthread_kill(thread.handle, .IO)) { |
| 1056 | else => false, | | |
| 1057 | }; | | |
| 1058 | } else switch (builtin.target.os.tag) { | | |
| 1059 | .linux => { | | |
| 1060 | const pid: posix.pid_t = pid: { | | |
| 1061 | const cached_pid = @atomicLoad(Pid, &t.pid, .monotonic); | | |
| 1062 | if (cached_pid != .unknown) break :pid @intFromEnum(cached_pid); | | |
| 1063 | const pid = std.os.linux.getpid(); | | |
| 1064 | @atomicStore(Pid, &t.pid, @enumFromInt(pid), .monotonic); | | |
| 1065 | break :pid pid; | | |
| 1066 | }; | | |
| 1067 | return switch (std.os.linux.tgkill(pid, @bitCast(thread.id), .IO)) { | | |
| 1068 | 0 => true, | 1067 | 0 => true, |
| 1069 | else => false, | 1068 | else => false, |
| 1070 | }; | 1069 | }; |
| | 1070 | } else switch (native_os) { |
| | 1071 | .linux => { |
| | 1072 | const pid: posix.pid_t = pid: { |
| | 1073 | const cached_pid = @atomicLoad(Pid, &t.pid, .monotonic); |
| | 1074 | if (cached_pid != .unknown) break :pid @intFromEnum(cached_pid); |
| | 1075 | const pid = std.os.linux.getpid(); |
| | 1076 | @atomicStore(Pid, &t.pid, @enumFromInt(pid), .monotonic); |
| | 1077 | break :pid pid; |
| | 1078 | }; |
| | 1079 | return switch (std.os.linux.tgkill(pid, @bitCast(thread.id), .IO)) { |
| | 1080 | 0 => true, |
| | 1081 | else => false, |
| | 1082 | }; |
| | 1083 | }, |
| | 1084 | .windows => { |
| | 1085 | var iosb: windows.IO_STATUS_BLOCK = undefined; |
| | 1086 | return switch (windows.ntdll.NtCancelSynchronousIoFile(thread.handle, null, &iosb)) { |
| | 1087 | .NOT_FOUND => true, // this might mean the operation hasn't started yet |
| | 1088 | .SUCCESS => false, // the OS confirmed that our cancelation worked |
| | 1089 | else => false, |
| | 1090 | }; |
| | 1091 | }, |
| | 1092 | else => return false, |
| 1071 | }, | 1093 | }, |
| 1072 | .windows => { | 1094 | |
| 1073 | var iosb: windows.IO_STATUS_BLOCK = undefined; | 1095 | .blocked_alertable_canceling => { |
| 1074 | return switch (windows.ntdll.NtCancelSynchronousIoFile(thread.handle, null, &iosb)) { | 1096 | if (!is_windows) unreachable; |
| 1075 | .NOT_FOUND => true, // this might mean the operation hasn't started yet | 1097 | return switch (windows.ntdll.NtAlertThread(thread.handle)) { |
| 1076 | .SUCCESS => false, // the OS confirmed that our cancelation worked | 1098 | .SUCCESS => true, |
| 1077 | else => false, | 1099 | else => false, |
| 1078 | }; | 1100 | }; |
| 1079 | }, | 1101 | }, |
| 1080 | else => return false, | 1102 | |
| | 1103 | else => { |
| | 1104 | // The thread is working on `awaitable`, but no longer needs signaling (they already |
| | 1105 | // woke up and saw the cancelation). |
| | 1106 | return false; |
| | 1107 | }, |
| 1081 | } | 1108 | } |
| 1082 | } | 1109 | } |
| 1083 | | 1110 | |
| ... | @@ -1118,7 +1145,8 @@ const Syscall = struct { | ... | @@ -1118,7 +1145,8 @@ const Syscall = struct { |
| 1118 | }, .monotonic).cancelation) { | 1145 | }, .monotonic).cancelation) { |
| 1119 | .parked => unreachable, | 1146 | .parked => unreachable, |
| 1120 | .blocked => unreachable, | 1147 | .blocked => unreachable, |
| 1121 | .blocked_windows_dns => unreachable, | 1148 | .blocked_alertable => unreachable, |
| | 1149 | .blocked_alertable_canceling => unreachable, |
| 1122 | .blocked_canceling => unreachable, | 1150 | .blocked_canceling => unreachable, |
| 1123 | .none => return .{ .thread = thread }, // new status is `.blocked` | 1151 | .none => return .{ .thread = thread }, // new status is `.blocked` |
| 1124 | .canceling => return error.Canceled, // new status is `.canceled` | 1152 | .canceling => return error.Canceled, // new status is `.canceled` |
| ... | @@ -1137,7 +1165,8 @@ const Syscall = struct { | ... | @@ -1137,7 +1165,8 @@ const Syscall = struct { |
| 1137 | }, .monotonic).cancelation) { | 1165 | }, .monotonic).cancelation) { |
| 1138 | .none => unreachable, | 1166 | .none => unreachable, |
| 1139 | .parked => unreachable, | 1167 | .parked => unreachable, |
| 1140 | .blocked_windows_dns => unreachable, | 1168 | .blocked_alertable => unreachable, |
| | 1169 | .blocked_alertable_canceling => unreachable, |
| 1141 | .canceling => unreachable, | 1170 | .canceling => unreachable, |
| 1142 | .canceled => unreachable, | 1171 | .canceled => unreachable, |
| 1143 | .blocked => {}, // new status is `.blocked` (unchanged) | 1172 | .blocked => {}, // new status is `.blocked` (unchanged) |
| ... | @@ -1153,13 +1182,41 @@ const Syscall = struct { | ... | @@ -1153,13 +1182,41 @@ const Syscall = struct { |
| 1153 | }, .monotonic).cancelation) { | 1182 | }, .monotonic).cancelation) { |
| 1154 | .none => unreachable, | 1183 | .none => unreachable, |
| 1155 | .parked => unreachable, | 1184 | .parked => unreachable, |
| 1156 | .blocked_windows_dns => unreachable, | 1185 | .blocked_alertable => unreachable, |
| | 1186 | .blocked_alertable_canceling => unreachable, |
| 1157 | .canceling => unreachable, | 1187 | .canceling => unreachable, |
| 1158 | .canceled => unreachable, | 1188 | .canceled => unreachable, |
| 1159 | .blocked => {}, // new status is `.none` | 1189 | .blocked => {}, // new status is `.none` |
| 1160 | .blocked_canceling => {}, // new status is `.canceling` | 1190 | .blocked_canceling => {}, // new status is `.canceling` |
| 1161 | } | 1191 | } |
| 1162 | } | 1192 | } |
| | 1193 | /// Indicates instead of `NtCancelSynchronousIoFile` we need to use |
| | 1194 | /// `NtAlertThread` to interrupt the wait. |
| | 1195 | /// |
| | 1196 | /// Windows only, called from blocked state only. |
| | 1197 | fn toAlertable(s: Syscall) Io.Cancelable!AlertableSyscall { |
| | 1198 | comptime assert(is_windows); |
| | 1199 | const thread = s.thread orelse return .{ .thread = null }; |
| | 1200 | var prev = thread.status.load(.monotonic); |
| | 1201 | while (true) prev = switch (prev.cancelation) { |
| | 1202 | .none => unreachable, |
| | 1203 | .parked => unreachable, |
| | 1204 | .blocked_alertable => unreachable, |
| | 1205 | .blocked_alertable_canceling => unreachable, |
| | 1206 | .canceling => unreachable, |
| | 1207 | .canceled => unreachable, |
| | 1208 | |
| | 1209 | .blocked => thread.status.cmpxchgWeak(prev, .{ |
| | 1210 | .cancelation = .blocked_alertable, |
| | 1211 | .awaitable = prev.awaitable, |
| | 1212 | }, .monotonic, .monotonic) orelse return .{ .thread = thread }, |
| | 1213 | |
| | 1214 | .blocked_canceling => thread.status.cmpxchgWeak(prev, .{ |
| | 1215 | .cancelation = .canceled, |
| | 1216 | .awaitable = prev.awaitable, |
| | 1217 | }, .monotonic, .monotonic) orelse return error.Canceled, |
| | 1218 | }; |
| | 1219 | } |
| 1163 | /// Convenience wrapper which calls `finish`, then returns `err`. | 1220 | /// Convenience wrapper which calls `finish`, then returns `err`. |
| 1164 | fn fail(s: Syscall, err: anytype) @TypeOf(err) { | 1221 | fn fail(s: Syscall, err: anytype) @TypeOf(err) { |
| 1165 | s.finish(); | 1222 | s.finish(); |
| ... | @@ -1191,6 +1248,72 @@ const Syscall = struct { | ... | @@ -1191,6 +1248,72 @@ const Syscall = struct { |
| 1191 | } | 1248 | } |
| 1192 | }; | 1249 | }; |
| 1193 | | 1250 | |
| | 1251 | const AlertableSyscall = struct { |
| | 1252 | thread: ?*Thread, |
| | 1253 | |
| | 1254 | comptime { |
| | 1255 | assert(is_windows); |
| | 1256 | } |
| | 1257 | |
| | 1258 | fn checkCancel(s: AlertableSyscall) Io.Cancelable!void { |
| | 1259 | comptime assert(is_windows); |
| | 1260 | const thread = s.thread orelse return; |
| | 1261 | const old_status = thread.status.fetchOr(.{ |
| | 1262 | .cancelation = @enumFromInt(0b010), |
| | 1263 | .awaitable = .null, |
| | 1264 | }, .monotonic); |
| | 1265 | switch (old_status.cancelation) { |
| | 1266 | .none => unreachable, |
| | 1267 | .parked => unreachable, |
| | 1268 | .blocked => unreachable, |
| | 1269 | .blocked_canceling => unreachable, |
| | 1270 | .canceling => unreachable, |
| | 1271 | .canceled => unreachable, |
| | 1272 | .blocked_alertable => {}, // new status is `.blocked_alertable` (unchanged) |
| | 1273 | .blocked_alertable_canceling => { |
| | 1274 | // New status is `.canceling`---change to `.canceled` before return. |
| | 1275 | thread.status.store(.{ .cancelation = .canceled, .awaitable = old_status.awaitable }, .monotonic); |
| | 1276 | return error.Canceled; |
| | 1277 | }, |
| | 1278 | } |
| | 1279 | } |
| | 1280 | |
| | 1281 | fn finish(s: AlertableSyscall) void { |
| | 1282 | comptime assert(is_windows); |
| | 1283 | const thread = s.thread orelse return; |
| | 1284 | switch (thread.status.fetchXor(.{ |
| | 1285 | .cancelation = @enumFromInt(0b010), |
| | 1286 | .awaitable = .null, |
| | 1287 | }, .monotonic).cancelation) { |
| | 1288 | .none => unreachable, |
| | 1289 | .parked => unreachable, |
| | 1290 | .blocked => unreachable, |
| | 1291 | .blocked_canceling => unreachable, |
| | 1292 | .canceling => unreachable, |
| | 1293 | .canceled => unreachable, |
| | 1294 | .blocked_alertable => {}, // new status is `.none` |
| | 1295 | .blocked_alertable_canceling => {}, // new status is `.canceling` |
| | 1296 | } |
| | 1297 | } |
| | 1298 | |
| | 1299 | fn fail(s: AlertableSyscall, err: anytype) @TypeOf(err) { |
| | 1300 | s.finish(); |
| | 1301 | return err; |
| | 1302 | } |
| | 1303 | |
| | 1304 | fn ntstatusBug(s: AlertableSyscall, status: windows.NTSTATUS) Io.UnexpectedError { |
| | 1305 | @branchHint(.cold); |
| | 1306 | s.finish(); |
| | 1307 | return windows.statusBug(status); |
| | 1308 | } |
| | 1309 | |
| | 1310 | fn unexpectedNtstatus(s: AlertableSyscall, status: windows.NTSTATUS) Io.UnexpectedError { |
| | 1311 | @branchHint(.cold); |
| | 1312 | s.finish(); |
| | 1313 | return windows.unexpectedStatus(status); |
| | 1314 | } |
| | 1315 | }; |
| | 1316 | |
| 1194 | const max_iovecs_len = 8; | 1317 | const max_iovecs_len = 8; |
| 1195 | const splat_buffer_size = 64; | 1318 | const splat_buffer_size = 64; |
| 1196 | const default_PATH = "/usr/local/bin:/bin/:/usr/bin"; | 1319 | const default_PATH = "/usr/local/bin:/bin/:/usr/bin"; |
| ... | @@ -1977,7 +2100,8 @@ fn groupAsyncEager( | ... | @@ -1977,7 +2100,8 @@ fn groupAsyncEager( |
| 1977 | .canceled => true, | 2100 | .canceled => true, |
| 1978 | .parked => unreachable, | 2101 | .parked => unreachable, |
| 1979 | .blocked => unreachable, | 2102 | .blocked => unreachable, |
| 1980 | .blocked_windows_dns => unreachable, | 2103 | .blocked_alertable => unreachable, |
| | 2104 | .blocked_alertable_canceling => unreachable, |
| 1981 | .blocked_canceling => unreachable, | 2105 | .blocked_canceling => unreachable, |
| 1982 | }; | 2106 | }; |
| 1983 | } else false; | 2107 | } else false; |
| ... | @@ -1988,7 +2112,8 @@ fn groupAsyncEager( | ... | @@ -1988,7 +2112,8 @@ fn groupAsyncEager( |
| 1988 | .canceled => true, | 2112 | .canceled => true, |
| 1989 | .parked => unreachable, | 2113 | .parked => unreachable, |
| 1990 | .blocked => unreachable, | 2114 | .blocked => unreachable, |
| 1991 | .blocked_windows_dns => unreachable, | 2115 | .blocked_alertable => unreachable, |
| | 2116 | .blocked_alertable_canceling => unreachable, |
| 1992 | .blocked_canceling => unreachable, | 2117 | .blocked_canceling => unreachable, |
| 1993 | }; | 2118 | }; |
| 1994 | } else false; | 2119 | } else false; |
| ... | @@ -2167,7 +2292,8 @@ fn recancelInner() void { | ... | @@ -2167,7 +2292,8 @@ fn recancelInner() void { |
| 2167 | .canceling => unreachable, // called `recancel` but cancelation was already pending | 2292 | .canceling => unreachable, // called `recancel` but cancelation was already pending |
| 2168 | .parked => unreachable, | 2293 | .parked => unreachable, |
| 2169 | .blocked => unreachable, | 2294 | .blocked => unreachable, |
| 2170 | .blocked_windows_dns => unreachable, | 2295 | .blocked_alertable => unreachable, |
| | 2296 | .blocked_alertable_canceling => unreachable, |
| 2171 | .blocked_canceling => unreachable, | 2297 | .blocked_canceling => unreachable, |
| 2172 | } | 2298 | } |
| 2173 | } | 2299 | } |
| ... | @@ -12096,8 +12222,7 @@ fn netLookupFallible( | ... | @@ -12096,8 +12222,7 @@ fn netLookupFallible( |
| 12096 | var res: *ws2_32.ADDRINFOEXW = undefined; | 12222 | var res: *ws2_32.ADDRINFOEXW = undefined; |
| 12097 | const timeout: ?*ws2_32.timeval = null; | 12223 | const timeout: ?*ws2_32.timeval = null; |
| 12098 | while (true) { | 12224 | while (true) { |
| 12099 | // TODO: hook this up to cancelation with `Thread.Status.cancelation.blocked_windows_dns`. | 12225 | // TODO: hook this up to cancelation with `NtDelayExecution` and APC callbacks. |
| 12100 | // See matching TODO in `Thread.cancelAwaitable`. | | |
| 12101 | try Thread.checkCancel(); | 12226 | try Thread.checkCancel(); |
| 12102 | // TODO make this append to the queue eagerly rather than blocking until the whole thing finishes | 12227 | // TODO make this append to the queue eagerly rather than blocking until the whole thing finishes |
| 12103 | const rc: ws2_32.WinsockError = @enumFromInt(ws2_32.GetAddrInfoExW(name_w, port_w, .DNS, null, &hints, &res, timeout, null, null, null)); | 12228 | const rc: ws2_32.WinsockError = @enumFromInt(ws2_32.GetAddrInfoExW(name_w, port_w, .DNS, null, &hints, &res, timeout, null, null, null)); |
| ... | @@ -15780,7 +15905,8 @@ const parking_futex = struct { | ... | @@ -15780,7 +15905,8 @@ const parking_futex = struct { |
| 15780 | .canceled => break :cancelable, // status is still `.canceled` | 15905 | .canceled => break :cancelable, // status is still `.canceled` |
| 15781 | .parked => unreachable, | 15906 | .parked => unreachable, |
| 15782 | .blocked => unreachable, | 15907 | .blocked => unreachable, |
| 15783 | .blocked_windows_dns => unreachable, | 15908 | .blocked_alertable => unreachable, |
| | 15909 | .blocked_alertable_canceling => unreachable, |
| 15784 | .blocked_canceling => unreachable, | 15910 | .blocked_canceling => unreachable, |
| 15785 | } | 15911 | } |
| 15786 | // We could now be unparked for a cancelation at any time! | 15912 | // We could now be unparked for a cancelation at any time! |
| ... | @@ -15831,7 +15957,8 @@ const parking_futex = struct { | ... | @@ -15831,7 +15957,8 @@ const parking_futex = struct { |
| 15831 | }, | 15957 | }, |
| 15832 | .canceled => unreachable, | 15958 | .canceled => unreachable, |
| 15833 | .blocked => unreachable, | 15959 | .blocked => unreachable, |
| 15834 | .blocked_windows_dns => unreachable, | 15960 | .blocked_alertable => unreachable, |
| | 15961 | .blocked_alertable_canceling => unreachable, |
| 15835 | .blocked_canceling => unreachable, | 15962 | .blocked_canceling => unreachable, |
| 15836 | }, | 15963 | }, |
| 15837 | } | 15964 | } |
| ... | @@ -15872,7 +15999,8 @@ const parking_futex = struct { | ... | @@ -15872,7 +15999,8 @@ const parking_futex = struct { |
| 15872 | .canceling => continue, // race with a canceler who hasn't called `removeCanceledWaiter` yet | 15999 | .canceling => continue, // race with a canceler who hasn't called `removeCanceledWaiter` yet |
| 15873 | .canceled => unreachable, | 16000 | .canceled => unreachable, |
| 15874 | .blocked => unreachable, | 16001 | .blocked => unreachable, |
| 15875 | .blocked_windows_dns => unreachable, | 16002 | .blocked_alertable => unreachable, |
| | 16003 | .blocked_alertable_canceling => unreachable, |
| 15876 | .blocked_canceling => unreachable, | 16004 | .blocked_canceling => unreachable, |
| 15877 | } | 16005 | } |
| 15878 | // We're waking this waiter. Remove them from the bucket and add them to our local list. | 16006 | // We're waking this waiter. Remove them from the bucket and add them to our local list. |
| ... | @@ -15938,7 +16066,8 @@ const parking_sleep = struct { | ... | @@ -15938,7 +16066,8 @@ const parking_sleep = struct { |
| 15938 | .canceled => break :cancelable, // status is still `.canceled` | 16066 | .canceled => break :cancelable, // status is still `.canceled` |
| 15939 | .parked => unreachable, | 16067 | .parked => unreachable, |
| 15940 | .blocked => unreachable, | 16068 | .blocked => unreachable, |
| 15941 | .blocked_windows_dns => unreachable, | 16069 | .blocked_alertable => unreachable, |
| | 16070 | .blocked_alertable_canceling => unreachable, |
| 15942 | .blocked_canceling => unreachable, | 16071 | .blocked_canceling => unreachable, |
| 15943 | } | 16072 | } |
| 15944 | while (park(deadline, null)) { | 16073 | while (park(deadline, null)) { |
| ... | @@ -15956,7 +16085,8 @@ const parking_sleep = struct { | ... | @@ -15956,7 +16085,8 @@ const parking_sleep = struct { |
| 15956 | .none => unreachable, | 16085 | .none => unreachable, |
| 15957 | .canceled => unreachable, | 16086 | .canceled => unreachable, |
| 15958 | .blocked => unreachable, | 16087 | .blocked => unreachable, |
| 15959 | .blocked_windows_dns => unreachable, | 16088 | .blocked_alertable => unreachable, |
| | 16089 | .blocked_alertable_canceling => unreachable, |
| 15960 | .blocked_canceling => unreachable, | 16090 | .blocked_canceling => unreachable, |
| 15961 | } | 16091 | } |
| 15962 | } else |err| switch (err) { | 16092 | } else |err| switch (err) { |
| ... | @@ -15975,7 +16105,8 @@ const parking_sleep = struct { | ... | @@ -15975,7 +16105,8 @@ const parking_sleep = struct { |
| 15975 | .none => unreachable, | 16105 | .none => unreachable, |
| 15976 | .canceled => unreachable, | 16106 | .canceled => unreachable, |
| 15977 | .blocked => unreachable, | 16107 | .blocked => unreachable, |
| 15978 | .blocked_windows_dns => unreachable, | 16108 | .blocked_alertable => unreachable, |
| | 16109 | .blocked_alertable_canceling => unreachable, |
| 15979 | .blocked_canceling => unreachable, | 16110 | .blocked_canceling => unreachable, |
| 15980 | }, | 16111 | }, |
| 15981 | } | 16112 | } |