authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-21 21:05:15-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-30 12:10:01-08:00
log0553525fe6679a1d9a1b67e5f9cec74876379b64
tree442e07079230441d478d9c9534c4cea1f6a972bc
parent1b157499efd0999e8fb8cff7a17dd3fcc9a56c59

std.Io.Threaded: introduce Thread.InterruptMethod

implements APC cancelation except for the actual call to NtCancelIoFileEx

1 files changed, 149 insertions(+), 92 deletions(-)

lib/std/Io/Threaded.zig+149-92
......@@ -339,8 +339,8 @@ const Group = struct {
339339 .canceled => true,
340340 .parked => unreachable,
341341 .blocked => unreachable,
342 .blocked_alertable => unreachable,
343 .blocked_alertable_canceling => unreachable,
342 .blocked_apc => unreachable,
343 .blocked_windows_dns => unreachable,
344344 .blocked_canceling => unreachable,
345345 };
346346 if (result) {
......@@ -379,7 +379,10 @@ const Group = struct {
379379 while (it) |thread| : (it = thread.next) {
380380 // This non-mutating RMW exists for ordering reasons: see comment in `Group.Task.start` for reasons.
381381 _ = thread.status.fetchOr(.{ .cancelation = @enumFromInt(0), .awaitable = .null }, .release);
382 if (thread.cancelAwaitable(.fromGroup(g.ptr))) any_blocked = true;
382 if (thread.cancelAwaitable(.fromGroup(g.ptr))) |method| {
383 thread.interrupt_method = method;
384 any_blocked = true;
385 }
383386 }
384387 return any_blocked;
385388 }
......@@ -391,7 +394,7 @@ const Group = struct {
391394 var any_signaled = false;
392395 var it = t.worker_threads.load(.acquire); // acquire `Thread` values
393396 while (it) |thread| : (it = thread.next) {
394 if (thread.signalCanceledSyscall(t, .fromGroup(g.ptr))) any_signaled = true;
397 if (thread.signalCanceledSyscall(t, .fromGroup(g.ptr), thread.interrupt_method)) any_signaled = true;
395398 }
396399 return any_signaled;
397400 }
......@@ -543,8 +546,8 @@ const Future = struct {
543546 .canceled => true,
544547 .parked => unreachable,
545548 .blocked => unreachable,
546 .blocked_alertable => unreachable,
547 .blocked_alertable_canceling => unreachable,
549 .blocked_apc => unreachable,
550 .blocked_windows_dns => unreachable,
548551 .blocked_canceling => unreachable,
549552 };
550553 thread.status.store(.{ .cancelation = .none, .awaitable = .null }, .monotonic);
......@@ -573,11 +576,15 @@ const Future = struct {
573576 num_completed: *std.atomic.Value(u32),
574577 thread: ?*Thread,
575578 ) void {
576 var need_signal: bool = if (thread) |th| th.cancelAwaitable(.fromFuture(future)) else false;
579 var interrupt_method: ?Thread.InterruptMethod =
580 if (thread) |th| th.cancelAwaitable(.fromFuture(future)) else null;
577581 var timeout_ns: u64 = 1 << 10;
578582 while (true) {
579 need_signal = need_signal and thread.?.signalCanceledSyscall(t, .fromFuture(future));
580 Thread.futexWaitUncancelable(&num_completed.raw, 0, if (need_signal) timeout_ns else null);
583 if (interrupt_method) |method| {
584 if (!thread.?.signalCanceledSyscall(t, .fromFuture(future), method))
585 interrupt_method = null;
586 }
587 Thread.futexWaitUncancelable(&num_completed.raw, 0, if (interrupt_method != null) timeout_ns else null);
581588 switch (num_completed.load(.acquire)) { // acquire task results
582589 0 => {},
583590 1 => break,
......@@ -625,6 +632,9 @@ const Thread = struct {
625632 cancel_protection: Io.CancelProtection,
626633 /// Always released when `Status.cancelation` is set to `.parked`.
627634 futex_waiter: if (use_parking_futex) ?*parking_futex.Waiter else ?noreturn,
635 apc_context: if (is_windows) ?*anyopaque else void,
636 /// Used only by group cancelation code for temporary storage.
637 interrupt_method: InterruptMethod,
628638
629639 csprng: Csprng,
630640
......@@ -652,11 +662,13 @@ const Thread = struct {
652662 /// To request cancelation, set the status to `.blocked_canceling` and repeatedly interrupt the system call until the status changes.
653663 blocked = 0b011,
654664
655 /// Windows-only: the thread is blocked in an alertable wait via
656 /// `NtDelayExecution`. To request cancelation, set the status to
657 /// `blocked_alertable_canceling` and repeatedly alert the thread
658 /// until the status changes.
659 blocked_alertable = 0b010,
665 /// Windows-only: the thread is blocked in a call to `NtDelayExecution`.
666 /// To request cancelation, set the status to `.canceling` and call `NtCancelIoFileEx`.
667 blocked_apc = 0b100,
668
669 /// Windows-only: the thread is blocked in a call to `GetAddrInfoExW`.
670 /// To request cancelation, set the status to `.canceling` and call `GetAddrInfoExCancel`.
671 blocked_windows_dns = 0b010,
660672
661673 /// The thread has an outstanding cancelation request but is not in a cancelable operation.
662674 /// When it acknowledges the cancelation, it will set the status to `.canceled`.
......@@ -705,8 +717,8 @@ const Thread = struct {
705717 switch (status.cancelation) {
706718 .parked => unreachable,
707719 .blocked => unreachable,
708 .blocked_alertable => unreachable,
709 .blocked_alertable_canceling => unreachable,
720 .blocked_apc => unreachable,
721 .blocked_windows_dns => unreachable,
710722 .blocked_canceling => unreachable,
711723 .none, .canceled => {},
712724 .canceling => {
......@@ -986,17 +998,17 @@ const Thread = struct {
986998 /// It is possible that `thread` gets canceled by this function, but is blocked in a syscall. In
987999 /// that case, the thread may need to be sent a signal to interrupt the call. This function will
9881000 /// return `true` to indicate this, in which case the caller must call `signalCanceledSyscall`.
989 fn cancelAwaitable(thread: *Thread, awaitable: AwaitableId) bool {
1001 fn cancelAwaitable(thread: *Thread, awaitable: AwaitableId) ?InterruptMethod {
9901002 var status = thread.status.load(.monotonic);
9911003 while (true) {
992 if (status.awaitable != awaitable) return false; // thread is working on something else
1004 if (status.awaitable != awaitable) return null; // thread is working on something else
9931005 status = switch (status.cancelation) {
9941006 .none => thread.status.cmpxchgWeak(
9951007 .{ .cancelation = .none, .awaitable = awaitable },
9961008 .{ .cancelation = .canceling, .awaitable = awaitable },
9971009 .monotonic,
9981010 .monotonic,
999 ) orelse return false,
1011 ) orelse return null,
10001012
10011013 .parked => thread.status.cmpxchgWeak(
10021014 .{ .cancelation = .parked, .awaitable = awaitable },
......@@ -1009,7 +1021,7 @@ const Thread = struct {
10091021 parking_futex.removeCanceledWaiter(futex_waiter);
10101022 }
10111023 unpark(&.{thread.id}, null);
1012 return false;
1024 return null;
10131025 },
10141026
10151027 .blocked => thread.status.cmpxchgWeak(
......@@ -1017,7 +1029,17 @@ const Thread = struct {
10171029 .{ .cancelation = .blocked_canceling, .awaitable = awaitable },
10181030 .monotonic,
10191031 .monotonic,
1020 ) orelse return true,
1032 ) orelse return .sync,
1033
1034 .blocked_apc => thread.status.cmpxchgWeak(
1035 .{ .cancelation = .blocked_apc, .awaitable = awaitable },
1036 .{ .cancelation = .canceling, .awaitable = awaitable },
1037 .monotonic,
1038 .monotonic,
1039 ) orelse {
1040 if (!is_windows) unreachable;
1041 return .apc;
1042 },
10211043
10221044 .blocked_alertable => thread.status.cmpxchgWeak(
10231045 .{ .cancelation = .blocked_alertable, .awaitable = awaitable },
......@@ -1026,14 +1048,14 @@ const Thread = struct {
10261048 .monotonic,
10271049 ) orelse {
10281050 if (!is_windows) unreachable;
1029 return true;
1051 return .dns;
10301052 },
10311053
10321054 .canceling, .canceled => {
10331055 // This can happen when the task start raced with the cancelation, so the thread
10341056 // saw the cancelation on the future/group *and* we are trying to signal the
10351057 // thread here.
1036 return false;
1058 return null;
10371059 },
10381060
10391061 .blocked_canceling => unreachable, // `awaitable` has not been canceled before now
......@@ -1042,6 +1064,11 @@ const Thread = struct {
10421064 }
10431065 }
10441066
1067 const InterruptMethod = switch (native_os) {
1068 .windows => enum { sync, dns, apc },
1069 else => enum { sync },
1070 };
1071
10451072 /// Sends a signal to `thread` if it is still blocked in a syscall (i.e. has not yet observed
10461073 /// the cancelation request from `cancelAwaitable`).
10471074 ///
......@@ -1051,24 +1078,21 @@ const Thread = struct {
10511078 /// the thread is still blocked. For the implementation, `Future.waitForCancelWithSignaling` and
10521079 /// `Group.waitForCancelWithSignaling`: they use exponential backoff starting at a 1us delay and
10531080 /// doubling each call. In practice, it is rare to send more than one signal.
1054 fn signalCanceledSyscall(thread: *Thread, t: *Threaded, awaitable: AwaitableId) bool {
1055 const status = thread.status.load(.monotonic);
1056 if (status.awaitable != awaitable) {
1057 // The thread has moved on and is working on something totally different.
1058 return false;
1059 }
1081 fn signalCanceledSyscall(thread: *Thread, t: *Threaded, awaitable: AwaitableId, method: InterruptMethod) bool {
1082 const bad_status: Status = .{ .cancelation = .blocked_canceling, .awaitable = awaitable };
1083 if (thread.status.load(.monotonic) != bad_status) return false;
10601084
10611085 // The thread ID and/or handle can be read non-atomically because they never change and were
10621086 // released by the store that made `thread` available to us.
10631087
1064 switch (status.cancelation) {
1065 .blocked_canceling => if (std.Thread.use_pthreads) {
1066 return switch (std.c.pthread_kill(thread.handle, .IO)) {
1067 0 => true,
1068 else => false,
1069 };
1070 } else switch (native_os) {
1071 .linux => {
1088 if (std.Thread.use_pthreads) switch (method) {
1089 .sync => return switch (std.c.pthread_kill(thread.handle, .IO)) {
1090 0 => true,
1091 else => false,
1092 },
1093 } else switch (native_os) {
1094 .linux => switch (method) {
1095 .sync => {
10721096 const pid: posix.pid_t = pid: {
10731097 const cached_pid = @atomicLoad(Pid, &t.pid, .monotonic);
10741098 if (cached_pid != .unknown) break :pid @intFromEnum(cached_pid);
......@@ -1081,7 +1105,9 @@ const Thread = struct {
10811105 else => false,
10821106 };
10831107 },
1084 .windows => {
1108 },
1109 .windows => switch (method) {
1110 .sync => {
10851111 var iosb: windows.IO_STATUS_BLOCK = undefined;
10861112 return switch (windows.ntdll.NtCancelSynchronousIoFile(thread.handle, null, &iosb)) {
10871113 .NOT_FOUND => true, // this might mean the operation hasn't started yet
......@@ -1089,15 +1115,8 @@ const Thread = struct {
10891115 else => false,
10901116 };
10911117 },
1092 else => return false,
1093 },
1094
1095 .blocked_alertable_canceling => {
1096 if (!is_windows) unreachable;
1097 return switch (windows.ntdll.NtAlertThread(thread.handle)) {
1098 .SUCCESS => true,
1099 else => false,
1100 };
1118 .dns => @panic("TODO call GetAddrInfoExCancel"),
1119 .apc => @panic("TODO call NtCancelIoFileEx"),
11011120 },
11021121
11031122 else => {
......@@ -1145,8 +1164,8 @@ const Syscall = struct {
11451164 }, .monotonic).cancelation) {
11461165 .parked => unreachable,
11471166 .blocked => unreachable,
1148 .blocked_alertable => unreachable,
1149 .blocked_alertable_canceling => unreachable,
1167 .blocked_apc => unreachable,
1168 .blocked_windows_dns => unreachable,
11501169 .blocked_canceling => unreachable,
11511170 .none => return .{ .thread = thread }, // new status is `.blocked`
11521171 .canceling => return error.Canceled, // new status is `.canceled`
......@@ -1165,19 +1184,14 @@ const Syscall = struct {
11651184 }, .monotonic).cancelation) {
11661185 .none => unreachable,
11671186 .parked => unreachable,
1168 .blocked_alertable => unreachable,
1169 .blocked_alertable_canceling => unreachable,
1187 .blocked_apc => unreachable,
1188 .blocked_windows_dns => unreachable,
11701189 .canceling => unreachable,
11711190 .canceled => unreachable,
11721191 .blocked => {}, // new status is `.blocked` (unchanged)
11731192 .blocked_canceling => return error.Canceled, // new status is `.canceled`
11741193 }
11751194 }
1176 fn toApc(s: Syscall) Io.Cancelable!void {
1177 // TODO set state to indicate instead of NtCancelSynchronousIoFile we
1178 // need to use NtCancelIoFileEx
1179 return s.checkCancel();
1180 }
11811195 /// Marks this syscall as finished.
11821196 fn finish(s: Syscall) void {
11831197 const thread = s.thread orelse return;
......@@ -1187,8 +1201,8 @@ const Syscall = struct {
11871201 }, .monotonic).cancelation) {
11881202 .none => unreachable,
11891203 .parked => unreachable,
1190 .blocked_alertable => unreachable,
1191 .blocked_alertable_canceling => unreachable,
1204 .blocked_apc => unreachable,
1205 .blocked_windows_dns => unreachable,
11921206 .canceling => unreachable,
11931207 .canceled => unreachable,
11941208 .blocked => {}, // new status is `.none`
......@@ -1196,25 +1210,25 @@ const Syscall = struct {
11961210 }
11971211 }
11981212 /// Indicates instead of `NtCancelSynchronousIoFile` we need to use
1199 /// `NtAlertThread` to interrupt the wait.
1213 /// `NtCancelIoFileEx` to interrupt the wait.
12001214 ///
12011215 /// Windows only, called from blocked state only.
1202 fn toAlertable(s: Syscall) Io.Cancelable!AlertableSyscall {
1203 comptime assert(is_windows);
1204 const thread = s.thread orelse return .{ .thread = null };
1216 fn toApc(s: Syscall, apc_context: ?*anyopaque) Io.Cancelable!void {
1217 const thread = s.thread orelse return;
1218 thread.apc_context = apc_context;
12051219 var prev = thread.status.load(.monotonic);
12061220 while (true) prev = switch (prev.cancelation) {
12071221 .none => unreachable,
12081222 .parked => unreachable,
1209 .blocked_alertable => unreachable,
1210 .blocked_alertable_canceling => unreachable,
1223 .blocked_apc => unreachable,
1224 .blocked_windows_dns => unreachable,
12111225 .canceling => unreachable,
12121226 .canceled => unreachable,
12131227
12141228 .blocked => thread.status.cmpxchgWeak(prev, .{
1215 .cancelation = .blocked_alertable,
1229 .cancelation = .blocked_apc,
12161230 .awaitable = prev.awaitable,
1217 }, .monotonic, .monotonic) orelse return .{ .thread = thread },
1231 }, .monotonic, .monotonic) orelse return,
12181232
12191233 .blocked_canceling => thread.status.cmpxchgWeak(prev, .{
12201234 .cancelation = .canceled,
......@@ -1222,6 +1236,45 @@ const Syscall = struct {
12221236 }, .monotonic, .monotonic) orelse return error.Canceled,
12231237 };
12241238 }
1239 /// Windows only, called from blocked_apc state only.
1240 fn checkCancelApc(s: Syscall) Io.Cancelable!void {
1241 const thread = s.thread orelse return;
1242 var prev = thread.status.load(.monotonic);
1243 while (true) prev = switch (prev.cancelation) {
1244 .none => unreachable,
1245 .parked => unreachable,
1246 .blocked_windows_dns => unreachable,
1247 .blocked => unreachable,
1248 .canceling => unreachable,
1249 .canceled => unreachable,
1250 .blocked_apc => return,
1251 .blocked_canceling => thread.status.cmpxchgWeak(prev, .{
1252 .cancelation = .canceled,
1253 .awaitable = prev.awaitable,
1254 }, .monotonic, .monotonic) orelse return error.Canceled,
1255 };
1256 }
1257 /// Windows only, called from blocked_apc state only.
1258 fn finishApc(s: Syscall) void {
1259 const thread = s.thread orelse return;
1260 var prev = thread.status.load(.monotonic);
1261 while (true) prev = switch (prev.cancelation) {
1262 .none => unreachable,
1263 .parked => unreachable,
1264 .blocked_windows_dns => unreachable,
1265 .blocked => unreachable,
1266 .canceling => unreachable,
1267 .canceled => unreachable,
1268 .blocked_apc => thread.status.cmpxchgWeak(prev, .{
1269 .cancelation = .none,
1270 .awaitable = prev.awaitable,
1271 }, .monotonic, .monotonic) orelse return,
1272 .blocked_canceling => thread.status.cmpxchgWeak(prev, .{
1273 .cancelation = .canceling,
1274 .awaitable = prev.awaitable,
1275 }, .monotonic, .monotonic) orelse return,
1276 };
1277 }
12251278 /// Convenience wrapper which calls `finish`, then returns `err`.
12261279 fn fail(s: Syscall, err: anytype) @TypeOf(err) {
12271280 s.finish();
......@@ -1501,6 +1554,8 @@ fn worker(t: *Threaded) void {
15011554 .cancel_protection = .unblocked,
15021555 .futex_waiter = undefined,
15031556 .csprng = .{},
1557 .apc_context = undefined,
1558 .interrupt_method = undefined,
15041559 };
15051560 Thread.current = &thread;
15061561
......@@ -2109,8 +2164,8 @@ fn groupAsyncEager(
21092164 .canceled => true,
21102165 .parked => unreachable,
21112166 .blocked => unreachable,
2112 .blocked_alertable => unreachable,
2113 .blocked_alertable_canceling => unreachable,
2167 .blocked_apc => unreachable,
2168 .blocked_windows_dns => unreachable,
21142169 .blocked_canceling => unreachable,
21152170 };
21162171 } else false;
......@@ -2121,8 +2176,8 @@ fn groupAsyncEager(
21212176 .canceled => true,
21222177 .parked => unreachable,
21232178 .blocked => unreachable,
2124 .blocked_alertable => unreachable,
2125 .blocked_alertable_canceling => unreachable,
2179 .blocked_apc => unreachable,
2180 .blocked_windows_dns => unreachable,
21262181 .blocked_canceling => unreachable,
21272182 };
21282183 } else false;
......@@ -2301,8 +2356,8 @@ fn recancelInner() void {
23012356 .canceling => unreachable, // called `recancel` but cancelation was already pending
23022357 .parked => unreachable,
23032358 .blocked => unreachable,
2304 .blocked_alertable => unreachable,
2305 .blocked_alertable_canceling => unreachable,
2359 .blocked_apc => unreachable,
2360 .blocked_windows_dns => unreachable,
23062361 .blocked_canceling => unreachable,
23072362 }
23082363}
......@@ -8376,6 +8431,7 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us
83768431 const buffer = data[index];
83778432
83788433 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
8434 var done: bool = false;
83798435
83808436 read: {
83818437 const syscall: Syscall = try .start();
......@@ -8383,8 +8439,8 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us
83838439 switch (windows.ntdll.NtReadFile(
83848440 file.handle,
83858441 null, // event
8386 noopApc, // apc callback
8387 null, // apc context
8442 flagApc, // apc callback
8443 &done, // apc context
83888444 &io_status_block,
83898445 buffer.ptr,
83908446 @min(std.math.maxInt(u32), buffer.len),
......@@ -8402,12 +8458,12 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us
84028458 //else => |status| return syscall.unexpectedNtstatus(status),
84038459 }
84048460 }
8405 try syscall.toApc();
8461 try syscall.toApc(&done);
84068462 while (true) {
84078463 switch (windows.ntdll.NtDelayExecution(1, null)) {
8408 .USER_APC => break syscall.finish(),
8464 .USER_APC => break syscall.finishApc(),
84098465 .SUCCESS, .CANCELLED => {
8410 try syscall.checkCancel();
8466 try syscall.checkCancelApc();
84118467 continue;
84128468 },
84138469 else => |status| std.debug.panic("fileReadStreamingWindows NtDelayExecution returned {t}", .{status}),
......@@ -8425,12 +8481,13 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us
84258481 return io_status_block.Information;
84268482}
84278483
8428fn noopApc(
8484fn flagApc(
84298485 apc_context: ?*anyopaque,
84308486 io_status_block: *windows.IO_STATUS_BLOCK,
84318487 unused: windows.ULONG,
84328488) callconv(.winapi) void {
8433 _ = apc_context;
8489 const flag: *bool = @ptrCast(apc_context);
8490 flag.* = true;
84348491 _ = io_status_block;
84358492 _ = unused;
84368493}
......@@ -12442,7 +12499,7 @@ fn netLookupFallible(
1244212499 var res: *ws2_32.ADDRINFOEXW = undefined;
1244312500 const timeout: ?*ws2_32.timeval = null;
1244412501 while (true) {
12445 // TODO: hook this up to cancelation with `NtDelayExecution` and APC callbacks.
12502 // TODO: hook this up to cancelation with `Thread.Status.cancelation.blocked_windows_dns`.
1244612503 try Thread.checkCancel();
1244712504 // TODO make this append to the queue eagerly rather than blocking until the whole thing finishes
1244812505 const rc: ws2_32.WinsockError = @enumFromInt(ws2_32.GetAddrInfoExW(name_w, port_w, .DNS, null, &hints, &res, timeout, null, null, null));
......@@ -16176,8 +16233,8 @@ const parking_futex = struct {
1617616233 .canceled => break :cancelable, // status is still `.canceled`
1617716234 .parked => unreachable,
1617816235 .blocked => unreachable,
16179 .blocked_alertable => unreachable,
16180 .blocked_alertable_canceling => unreachable,
16236 .blocked_apc => unreachable,
16237 .blocked_windows_dns => unreachable,
1618116238 .blocked_canceling => unreachable,
1618216239 }
1618316240 // We could now be unparked for a cancelation at any time!
......@@ -16228,8 +16285,8 @@ const parking_futex = struct {
1622816285 },
1622916286 .canceled => unreachable,
1623016287 .blocked => unreachable,
16231 .blocked_alertable => unreachable,
16232 .blocked_alertable_canceling => unreachable,
16288 .blocked_apc => unreachable,
16289 .blocked_windows_dns => unreachable,
1623316290 .blocked_canceling => unreachable,
1623416291 },
1623516292 }
......@@ -16270,8 +16327,8 @@ const parking_futex = struct {
1627016327 .canceling => continue, // race with a canceler who hasn't called `removeCanceledWaiter` yet
1627116328 .canceled => unreachable,
1627216329 .blocked => unreachable,
16273 .blocked_alertable => unreachable,
16274 .blocked_alertable_canceling => unreachable,
16330 .blocked_apc => unreachable,
16331 .blocked_windows_dns => unreachable,
1627516332 .blocked_canceling => unreachable,
1627616333 }
1627716334 // We're waking this waiter. Remove them from the bucket and add them to our local list.
......@@ -16337,8 +16394,8 @@ const parking_sleep = struct {
1633716394 .canceled => break :cancelable, // status is still `.canceled`
1633816395 .parked => unreachable,
1633916396 .blocked => unreachable,
16340 .blocked_alertable => unreachable,
16341 .blocked_alertable_canceling => unreachable,
16397 .blocked_apc => unreachable,
16398 .blocked_windows_dns => unreachable,
1634216399 .blocked_canceling => unreachable,
1634316400 }
1634416401 while (park(deadline, null)) {
......@@ -16356,8 +16413,8 @@ const parking_sleep = struct {
1635616413 .none => unreachable,
1635716414 .canceled => unreachable,
1635816415 .blocked => unreachable,
16359 .blocked_alertable => unreachable,
16360 .blocked_alertable_canceling => unreachable,
16416 .blocked_apc => unreachable,
16417 .blocked_windows_dns => unreachable,
1636116418 .blocked_canceling => unreachable,
1636216419 }
1636316420 } else |err| switch (err) {
......@@ -16376,8 +16433,8 @@ const parking_sleep = struct {
1637616433 .none => unreachable,
1637716434 .canceled => unreachable,
1637816435 .blocked => unreachable,
16379 .blocked_alertable => unreachable,
16380 .blocked_alertable_canceling => unreachable,
16436 .blocked_apc => unreachable,
16437 .blocked_windows_dns => unreachable,
1638116438 .blocked_canceling => unreachable,
1638216439 },
1638316440 }