authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-01 19:02:09-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-01 19:17:52-08:00
logbf0ffc45b9ca76250749097522714b7e3831a0c1
tree8cb4cc7f7a002d5282cfa23d46054ccca627d846
parent54a84964f8e3cd015688c6929612f7438b7e9553

std.Io.Threaded: musl: handle ECANCELED same as EINTR

Otherwise the pthread_cancel can affect unrelated tasks.

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

lib/std/Io/Threaded.zig+92-155
...@@ -93,10 +93,10 @@ pub const Pid = if (native_os == .linux) enum(posix.pid_t) {...@@ -93,10 +93,10 @@ pub const Pid = if (native_os == .linux) enum(posix.pid_t) {
93const Thread = struct {93const Thread = struct {
94 /// The value that needs to be passed to pthread_kill or tgkill in order to94 /// The value that needs to be passed to pthread_kill or tgkill in order to
95 /// send a signal.95 /// send a signal.
96 signal_id: SignalId,96 signal_id: SignaleeId,
97 current_closure: ?*Closure = null,97 current_closure: ?*Closure = null,
9898
99 const SignalId = if (std.Thread.use_pthreads) std.c.pthread_t else std.Thread.Id;99 const SignaleeId = if (std.Thread.use_pthreads) std.c.pthread_t else std.Thread.Id;
100100
101 threadlocal var current: ?*Thread = null;101 threadlocal var current: ?*Thread = null;
102102
...@@ -113,11 +113,15 @@ const Thread = struct {...@@ -113,11 +113,15 @@ const Thread = struct {
113 .acknowledged,113 .acknowledged,
114 .acq_rel,114 .acq_rel,
115 .acquire,115 .acquire,
116 ) orelse return error.Canceled) {116 ) orelse {
117 .none => return,117 if (is_musl) assert(std.c.pthread_setcancelstate(.DISABLE, null) == .SUCCESS);
118 return error.Canceled;
119 }) {
118 .requested => unreachable,120 .requested => unreachable,
119 .acknowledged => unreachable,121 .acknowledged => unreachable,
120 _ => return,122 .none, _ => {
123 if (is_musl) assert(std.c.pthread_setcancelstate(.MASKED, null) == .SUCCESS);
124 },
121 }125 }
122 }126 }
123127
...@@ -128,13 +132,14 @@ const Thread = struct {...@@ -128,13 +132,14 @@ const Thread = struct {
128 CancelStatus,132 CancelStatus,
129 &closure.cancel_status,133 &closure.cancel_status,
130 .none,134 .none,
131 .fromSignalId(thread.signal_id),135 .fromSignaleeId(thread.signal_id),
132 .acq_rel,136 .acq_rel,
133 .acquire,137 .acquire,
134 ) orelse return) {138 ) orelse return) {
135 .none => unreachable,139 .none => unreachable,
136 .requested => {140 .requested => {
137 @atomicStore(CancelStatus, &closure.cancel_status, .acknowledged, .release);141 @atomicStore(CancelStatus, &closure.cancel_status, .acknowledged, .release);
142 if (is_musl) assert(std.c.pthread_setcancelstate(.DISABLE, null) == .SUCCESS);
138 return error.Canceled;143 return error.Canceled;
139 },144 },
140 .acknowledged => return,145 .acknowledged => return,
...@@ -144,24 +149,22 @@ const Thread = struct {...@@ -144,24 +149,22 @@ const Thread = struct {
144149
145 fn endSyscall(thread: *Thread) void {150 fn endSyscall(thread: *Thread) void {
146 const closure = thread.current_closure orelse return;151 const closure = thread.current_closure orelse return;
147 _ = @cmpxchgStrong(152 const prev = @cmpxchgStrong(
148 CancelStatus,153 CancelStatus,
149 &closure.cancel_status,154 &closure.cancel_status,
150 .fromSignalId(thread.signal_id),155 .fromSignaleeId(thread.signal_id),
151 .none,156 .none,
152 .acq_rel,157 .acq_rel,
153 .acquire,158 .acquire,
154 );159 ) orelse return;
155 }160 if (is_musl and prev == .requested) {
156161 // They called pthread_cancel, but we want to disarm it since
157 fn endSyscallCanceled(thread: *Thread) Io.Cancelable {162 // the next call to beginSyscall will notice requested status.
158 if (thread.current_closure) |closure| {163 assert(std.c.pthread_setcancelstate(.DISABLE, null) == .SUCCESS);
159 @atomicStore(CancelStatus, &closure.cancel_status, .acknowledged, .release);
160 }164 }
161 return error.Canceled;
162 }165 }
163166
164 fn currentSignalId() SignalId {167 fn currentSignalId() SignaleeId {
165 return if (std.Thread.use_pthreads) std.c.pthread_self() else std.Thread.getCurrentId();168 return if (std.Thread.use_pthreads) std.c.pthread_self() else std.Thread.getCurrentId();
166 }169 }
167};170};
...@@ -184,7 +187,7 @@ const CancelStatus = enum(usize) {...@@ -184,7 +187,7 @@ const CancelStatus = enum(usize) {
184 /// Cancellation has been acknowledged and is in progress. Signals should187 /// Cancellation has been acknowledged and is in progress. Signals should
185 /// not be sent.188 /// not be sent.
186 acknowledged = std.math.maxInt(usize),189 acknowledged = std.math.maxInt(usize),
187 /// Stores a `Thread.SignalId` and indicates that sending a signal to this thread190 /// Stores a `Thread.SignaleeId` and indicates that sending a signal to this thread
188 /// is needed in order to cancel. This state is set before going into191 /// is needed in order to cancel. This state is set before going into
189 /// a blocking operation that needs to get unblocked via signal.192 /// a blocking operation that needs to get unblocked via signal.
190 _,193 _,
...@@ -193,7 +196,7 @@ const CancelStatus = enum(usize) {...@@ -193,7 +196,7 @@ const CancelStatus = enum(usize) {
193 none,196 none,
194 requested,197 requested,
195 acknowledged,198 acknowledged,
196 signal_id: Thread.SignalId,199 signal_id: Thread.SignaleeId,
197 };200 };
198201
199 fn unpack(cs: CancelStatus) Unpacked {202 fn unpack(cs: CancelStatus) Unpacked {
...@@ -210,7 +213,7 @@ const CancelStatus = enum(usize) {...@@ -210,7 +213,7 @@ const CancelStatus = enum(usize) {
210 };213 };
211 }214 }
212215
213 fn fromSignalId(signal_id: Thread.SignalId) CancelStatus {216 fn fromSignaleeId(signal_id: Thread.SignaleeId) CancelStatus {
214 return if (std.Thread.use_pthreads)217 return if (std.Thread.use_pthreads)
215 @enumFromInt(@intFromPtr(signal_id))218 @enumFromInt(@intFromPtr(signal_id))
216 else219 else
...@@ -397,6 +400,10 @@ fn worker(t: *Threaded) void {...@@ -397,6 +400,10 @@ fn worker(t: *Threaded) void {
397400
398 // Musl has an undocumented extension that makes pthread_cancel have the useful, desired401 // Musl has an undocumented extension that makes pthread_cancel have the useful, desired
399 // behavior of causing the next syscall to return ECANCELED.402 // behavior of causing the next syscall to return ECANCELED.
403 //
404 // The call to `requestCancel` and this can race, leading to
405 // ECANCELED being returned for a syscall in an unrelated task,
406 // which is why EINTR and ECANCELED are both handled with a check.
400 if (is_musl) assert(std.c.pthread_setcancelstate(.MASKED, null) == .SUCCESS);407 if (is_musl) assert(std.c.pthread_setcancelstate(.MASKED, null) == .SUCCESS);
401408
402 const closure: *Closure = @fieldParentPtr("node", closure_node);409 const closure: *Closure = @fieldParentPtr("node", closure_node);
...@@ -1239,11 +1246,10 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:...@@ -1239,11 +1246,10 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:
1239 current_thread.endSyscall();1246 current_thread.endSyscall();
1240 return;1247 return;
1241 },1248 },
1242 .INTR => {1249 .INTR, .CANCELED => {
1243 try current_thread.checkCancel();1250 try current_thread.checkCancel();
1244 continue;1251 continue;
1245 },1252 },
1246 .CANCELED => return current_thread.endSyscallCanceled(),
1247 else => |e| {1253 else => |e| {
1248 current_thread.endSyscall();1254 current_thread.endSyscall();
1249 switch (e) {1255 switch (e) {
...@@ -1282,11 +1288,10 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: I...@@ -1282,11 +1288,10 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: I
1282 current_thread.endSyscall();1288 current_thread.endSyscall();
1283 return;1289 return;
1284 },1290 },
1285 .INTR => {1291 .INTR, .CANCELED => {
1286 try current_thread.checkCancel();1292 try current_thread.checkCancel();
1287 continue;1293 continue;
1288 },1294 },
1289 .CANCELED => return current_thread.endSyscallCanceled(),
1290 else => |e| {1295 else => |e| {
1291 current_thread.endSyscall();1296 current_thread.endSyscall();
1292 switch (e) {1297 switch (e) {
...@@ -1548,11 +1553,10 @@ fn dirStatPathLinux(...@@ -1548,11 +1553,10 @@ fn dirStatPathLinux(
1548 current_thread.endSyscall();1553 current_thread.endSyscall();
1549 return statFromLinux(&statx);1554 return statFromLinux(&statx);
1550 },1555 },
1551 .INTR => {1556 .INTR, .CANCELED => {
1552 try current_thread.checkCancel();1557 try current_thread.checkCancel();
1553 continue;1558 continue;
1554 },1559 },
1555 .CANCELED => return current_thread.endSyscallCanceled(),
1556 else => |e| {1560 else => |e| {
1557 current_thread.endSyscall();1561 current_thread.endSyscall();
1558 switch (e) {1562 switch (e) {
...@@ -1594,11 +1598,10 @@ fn dirStatPathPosix(...@@ -1594,11 +1598,10 @@ fn dirStatPathPosix(
1594 current_thread.endSyscall();1598 current_thread.endSyscall();
1595 return statFromPosix(&stat);1599 return statFromPosix(&stat);
1596 },1600 },
1597 .INTR => {1601 .INTR, .CANCELED => {
1598 try current_thread.checkCancel();1602 try current_thread.checkCancel();
1599 continue;1603 continue;
1600 },1604 },
1601 .CANCELED => return current_thread.endSyscallCanceled(),
1602 else => |e| {1605 else => |e| {
1603 current_thread.endSyscall();1606 current_thread.endSyscall();
1604 switch (e) {1607 switch (e) {
...@@ -1655,11 +1658,10 @@ fn dirStatPathWasi(...@@ -1655,11 +1658,10 @@ fn dirStatPathWasi(
1655 current_thread.endSyscall();1658 current_thread.endSyscall();
1656 return statFromWasi(&stat);1659 return statFromWasi(&stat);
1657 },1660 },
1658 .INTR => {1661 .INTR, .CANCELED => {
1659 try current_thread.checkCancel();1662 try current_thread.checkCancel();
1660 continue;1663 continue;
1661 },1664 },
1662 .CANCELED => return current_thread.endSyscallCanceled(),
1663 else => |e| {1665 else => |e| {
1664 current_thread.endSyscall();1666 current_thread.endSyscall();
1665 switch (e) {1667 switch (e) {
...@@ -1701,11 +1703,10 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File...@@ -1701,11 +1703,10 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
1701 current_thread.endSyscall();1703 current_thread.endSyscall();
1702 return statFromPosix(&stat);1704 return statFromPosix(&stat);
1703 },1705 },
1704 .INTR => {1706 .INTR, .CANCELED => {
1705 try current_thread.checkCancel();1707 try current_thread.checkCancel();
1706 continue;1708 continue;
1707 },1709 },
1708 .CANCELED => return current_thread.endSyscallCanceled(),
1709 else => |e| {1710 else => |e| {
1710 current_thread.endSyscall();1711 current_thread.endSyscall();
1711 switch (e) {1712 switch (e) {
...@@ -1740,11 +1741,10 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File...@@ -1740,11 +1741,10 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
1740 current_thread.endSyscall();1741 current_thread.endSyscall();
1741 return statFromLinux(&statx);1742 return statFromLinux(&statx);
1742 },1743 },
1743 .INTR => {1744 .INTR, .CANCELED => {
1744 try current_thread.checkCancel();1745 try current_thread.checkCancel();
1745 continue;1746 continue;
1746 },1747 },
1747 .CANCELED => return current_thread.endSyscallCanceled(),
1748 else => |e| {1748 else => |e| {
1749 current_thread.endSyscall();1749 current_thread.endSyscall();
1750 switch (e) {1750 switch (e) {
...@@ -1826,11 +1826,10 @@ fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File....@@ -1826,11 +1826,10 @@ fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.
1826 current_thread.endSyscall();1826 current_thread.endSyscall();
1827 return statFromWasi(&stat);1827 return statFromWasi(&stat);
1828 },1828 },
1829 .INTR => {1829 .INTR, .CANCELED => {
1830 try current_thread.checkCancel();1830 try current_thread.checkCancel();
1831 continue;1831 continue;
1832 },1832 },
1833 .CANCELED => return current_thread.endSyscallCanceled(),
1834 else => |e| {1833 else => |e| {
1835 current_thread.endSyscall();1834 current_thread.endSyscall();
1836 switch (e) {1835 switch (e) {
...@@ -1878,11 +1877,10 @@ fn dirAccessPosix(...@@ -1878,11 +1877,10 @@ fn dirAccessPosix(
1878 current_thread.endSyscall();1877 current_thread.endSyscall();
1879 return;1878 return;
1880 },1879 },
1881 .INTR => {1880 .INTR, .CANCELED => {
1882 try current_thread.checkCancel();1881 try current_thread.checkCancel();
1883 continue;1882 continue;
1884 },1883 },
1885 .CANCELED => return current_thread.endSyscallCanceled(),
1886 else => |e| {1884 else => |e| {
1887 current_thread.endSyscall();1885 current_thread.endSyscall();
1888 switch (e) {1886 switch (e) {
...@@ -1928,11 +1926,10 @@ fn dirAccessWasi(...@@ -1928,11 +1926,10 @@ fn dirAccessWasi(
1928 current_thread.endSyscall();1926 current_thread.endSyscall();
1929 break;1927 break;
1930 },1928 },
1931 .INTR => {1929 .INTR, .CANCELED => {
1932 try current_thread.checkCancel();1930 try current_thread.checkCancel();
1933 continue;1931 continue;
1934 },1932 },
1935 .CANCELED => return current_thread.endSyscallCanceled(),
1936 else => |e| {1933 else => |e| {
1937 current_thread.endSyscall();1934 current_thread.endSyscall();
1938 switch (e) {1935 switch (e) {
...@@ -2075,11 +2072,10 @@ fn dirCreateFilePosix(...@@ -2075,11 +2072,10 @@ fn dirCreateFilePosix(
2075 current_thread.endSyscall();2072 current_thread.endSyscall();
2076 break @intCast(rc);2073 break @intCast(rc);
2077 },2074 },
2078 .INTR => {2075 .INTR, .CANCELED => {
2079 try current_thread.checkCancel();2076 try current_thread.checkCancel();
2080 continue;2077 continue;
2081 },2078 },
2082 .CANCELED => return current_thread.endSyscallCanceled(),
2083 else => |e| {2079 else => |e| {
2084 current_thread.endSyscall();2080 current_thread.endSyscall();
2085 switch (e) {2081 switch (e) {
...@@ -2130,11 +2126,10 @@ fn dirCreateFilePosix(...@@ -2130,11 +2126,10 @@ fn dirCreateFilePosix(
2130 current_thread.endSyscall();2126 current_thread.endSyscall();
2131 break;2127 break;
2132 },2128 },
2133 .INTR => {2129 .INTR, .CANCELED => {
2134 try current_thread.checkCancel();2130 try current_thread.checkCancel();
2135 continue;2131 continue;
2136 },2132 },
2137 .CANCELED => return current_thread.endSyscallCanceled(),
2138 else => |e| {2133 else => |e| {
2139 current_thread.endSyscall();2134 current_thread.endSyscall();
2140 switch (e) {2135 switch (e) {
...@@ -2159,7 +2154,7 @@ fn dirCreateFilePosix(...@@ -2159,7 +2154,7 @@ fn dirCreateFilePosix(
2159 current_thread.endSyscall();2154 current_thread.endSyscall();
2160 break @intCast(rc);2155 break @intCast(rc);
2161 },2156 },
2162 .INTR => {2157 .INTR, .CANCELED => {
2163 try current_thread.checkCancel();2158 try current_thread.checkCancel();
2164 continue;2159 continue;
2165 },2160 },
...@@ -2179,7 +2174,7 @@ fn dirCreateFilePosix(...@@ -2179,7 +2174,7 @@ fn dirCreateFilePosix(
2179 current_thread.endSyscall();2174 current_thread.endSyscall();
2180 break;2175 break;
2181 },2176 },
2182 .INTR => {2177 .INTR, .CANCELED => {
2183 try current_thread.checkCancel();2178 try current_thread.checkCancel();
2184 continue;2179 continue;
2185 },2180 },
...@@ -2285,11 +2280,10 @@ fn dirCreateFileWasi(...@@ -2285,11 +2280,10 @@ fn dirCreateFileWasi(
2285 current_thread.endSyscall();2280 current_thread.endSyscall();
2286 return .{ .handle = fd };2281 return .{ .handle = fd };
2287 },2282 },
2288 .INTR => {2283 .INTR, .CANCELED => {
2289 try current_thread.checkCancel();2284 try current_thread.checkCancel();
2290 continue;2285 continue;
2291 },2286 },
2292 .CANCELED => return current_thread.endSyscallCanceled(),
2293 else => |e| {2287 else => |e| {
2294 current_thread.endSyscall();2288 current_thread.endSyscall();
2295 switch (e) {2289 switch (e) {
...@@ -2379,11 +2373,10 @@ fn dirOpenFilePosix(...@@ -2379,11 +2373,10 @@ fn dirOpenFilePosix(
2379 current_thread.endSyscall();2373 current_thread.endSyscall();
2380 break @intCast(rc);2374 break @intCast(rc);
2381 },2375 },
2382 .INTR => {2376 .INTR, .CANCELED => {
2383 try current_thread.checkCancel();2377 try current_thread.checkCancel();
2384 continue;2378 continue;
2385 },2379 },
2386 .CANCELED => return current_thread.endSyscallCanceled(),
2387 else => |e| {2380 else => |e| {
2388 current_thread.endSyscall();2381 current_thread.endSyscall();
2389 switch (e) {2382 switch (e) {
...@@ -2433,11 +2426,10 @@ fn dirOpenFilePosix(...@@ -2433,11 +2426,10 @@ fn dirOpenFilePosix(
2433 current_thread.endSyscall();2426 current_thread.endSyscall();
2434 break;2427 break;
2435 },2428 },
2436 .INTR => {2429 .INTR, .CANCELED => {
2437 try current_thread.checkCancel();2430 try current_thread.checkCancel();
2438 continue;2431 continue;
2439 },2432 },
2440 .CANCELED => return current_thread.endSyscallCanceled(),
2441 else => |e| {2433 else => |e| {
2442 current_thread.endSyscall();2434 current_thread.endSyscall();
2443 switch (e) {2435 switch (e) {
...@@ -2462,11 +2454,10 @@ fn dirOpenFilePosix(...@@ -2462,11 +2454,10 @@ fn dirOpenFilePosix(
2462 current_thread.endSyscall();2454 current_thread.endSyscall();
2463 break @intCast(rc);2455 break @intCast(rc);
2464 },2456 },
2465 .INTR => {2457 .INTR, .CANCELED => {
2466 try current_thread.checkCancel();2458 try current_thread.checkCancel();
2467 continue;2459 continue;
2468 },2460 },
2469 .CANCELED => return current_thread.endSyscallCanceled(),
2470 else => |err| {2461 else => |err| {
2471 current_thread.endSyscall();2462 current_thread.endSyscall();
2472 return posix.unexpectedErrno(err);2463 return posix.unexpectedErrno(err);
...@@ -2483,11 +2474,10 @@ fn dirOpenFilePosix(...@@ -2483,11 +2474,10 @@ fn dirOpenFilePosix(
2483 current_thread.endSyscall();2474 current_thread.endSyscall();
2484 break;2475 break;
2485 },2476 },
2486 .INTR => {2477 .INTR, .CANCELED => {
2487 try current_thread.checkCancel();2478 try current_thread.checkCancel();
2488 continue;2479 continue;
2489 },2480 },
2490 .CANCELED => return current_thread.endSyscallCanceled(),
2491 else => |err| {2481 else => |err| {
2492 current_thread.endSyscall();2482 current_thread.endSyscall();
2493 return posix.unexpectedErrno(err);2483 return posix.unexpectedErrno(err);
...@@ -2682,11 +2672,10 @@ fn dirOpenFileWasi(...@@ -2682,11 +2672,10 @@ fn dirOpenFileWasi(
2682 current_thread.endSyscall();2672 current_thread.endSyscall();
2683 return .{ .handle = fd };2673 return .{ .handle = fd };
2684 },2674 },
2685 .INTR => {2675 .INTR, .CANCELED => {
2686 try current_thread.checkCancel();2676 try current_thread.checkCancel();
2687 continue;2677 continue;
2688 },2678 },
2689 .CANCELED => return current_thread.endSyscallCanceled(),
2690 else => |e| {2679 else => |e| {
2691 current_thread.endSyscall();2680 current_thread.endSyscall();
2692 switch (e) {2681 switch (e) {
...@@ -2766,11 +2755,10 @@ fn dirOpenDirPosix(...@@ -2766,11 +2755,10 @@ fn dirOpenDirPosix(
2766 current_thread.endSyscall();2755 current_thread.endSyscall();
2767 return .{ .handle = @intCast(rc) };2756 return .{ .handle = @intCast(rc) };
2768 },2757 },
2769 .INTR => {2758 .INTR, .CANCELED => {
2770 try current_thread.checkCancel();2759 try current_thread.checkCancel();
2771 continue;2760 continue;
2772 },2761 },
2773 .CANCELED => return current_thread.endSyscallCanceled(),
2774 else => |e| {2762 else => |e| {
2775 current_thread.endSyscall();2763 current_thread.endSyscall();
2776 switch (e) {2764 switch (e) {
...@@ -2819,11 +2807,10 @@ fn dirOpenDirHaiku(...@@ -2819,11 +2807,10 @@ fn dirOpenDirHaiku(
2819 return .{ .handle = rc };2807 return .{ .handle = rc };
2820 }2808 }
2821 switch (@as(posix.E, @enumFromInt(rc))) {2809 switch (@as(posix.E, @enumFromInt(rc))) {
2822 .INTR => {2810 .INTR, .CANCELED => {
2823 try current_thread.checkCancel();2811 try current_thread.checkCancel();
2824 continue;2812 continue;
2825 },2813 },
2826 .CANCELED => return current_thread.endSyscallCanceled(),
2827 else => |e| {2814 else => |e| {
2828 current_thread.endSyscall();2815 current_thread.endSyscall();
2829 switch (e) {2816 switch (e) {
...@@ -2964,11 +2951,10 @@ fn dirOpenDirWasi(...@@ -2964,11 +2951,10 @@ fn dirOpenDirWasi(
2964 current_thread.endSyscall();2951 current_thread.endSyscall();
2965 return .{ .handle = fd };2952 return .{ .handle = fd };
2966 },2953 },
2967 .INTR => {2954 .INTR, .CANCELED => {
2968 try current_thread.checkCancel();2955 try current_thread.checkCancel();
2969 continue;2956 continue;
2970 },2957 },
2971 .CANCELED => return current_thread.endSyscallCanceled(),
2972 else => |e| {2958 else => |e| {
2973 current_thread.endSyscall();2959 current_thread.endSyscall();
2974 switch (e) {2960 switch (e) {
...@@ -3031,11 +3017,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io...@@ -3031,11 +3017,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io
3031 current_thread.endSyscall();3017 current_thread.endSyscall();
3032 return nread;3018 return nread;
3033 },3019 },
3034 .INTR => {3020 .INTR, .CANCELED => {
3035 try current_thread.checkCancel();3021 try current_thread.checkCancel();
3036 continue;3022 continue;
3037 },3023 },
3038 .CANCELED => return current_thread.endSyscallCanceled(),
3039 else => |e| {3024 else => |e| {
3040 current_thread.endSyscall();3025 current_thread.endSyscall();
3041 switch (e) {3026 switch (e) {
...@@ -3065,11 +3050,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io...@@ -3065,11 +3050,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io
3065 current_thread.endSyscall();3050 current_thread.endSyscall();
3066 return @intCast(rc);3051 return @intCast(rc);
3067 },3052 },
3068 .INTR => {3053 .INTR, .CANCELED => {
3069 try current_thread.checkCancel();3054 try current_thread.checkCancel();
3070 continue;3055 continue;
3071 },3056 },
3072 .CANCELED => return current_thread.endSyscallCanceled(),
3073 else => |e| {3057 else => |e| {
3074 current_thread.endSyscall();3058 current_thread.endSyscall();
3075 switch (e) {3059 switch (e) {
...@@ -3151,11 +3135,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o...@@ -3151,11 +3135,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o
3151 current_thread.endSyscall();3135 current_thread.endSyscall();
3152 return nread;3136 return nread;
3153 },3137 },
3154 .INTR => {3138 .INTR, .CANCELED => {
3155 try current_thread.checkCancel();3139 try current_thread.checkCancel();
3156 continue;3140 continue;
3157 },3141 },
3158 .CANCELED => return current_thread.endSyscallCanceled(),
3159 else => |e| {3142 else => |e| {
3160 current_thread.endSyscall();3143 current_thread.endSyscall();
3161 switch (e) {3144 switch (e) {
...@@ -3189,11 +3172,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o...@@ -3189,11 +3172,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o
3189 current_thread.endSyscall();3172 current_thread.endSyscall();
3190 return @bitCast(rc);3173 return @bitCast(rc);
3191 },3174 },
3192 .INTR => {3175 .INTR, .CANCELED => {
3193 try current_thread.checkCancel();3176 try current_thread.checkCancel();
3194 continue;3177 continue;
3195 },3178 },
3196 .CANCELED => return current_thread.endSyscallCanceled(),
3197 else => |e| {3179 else => |e| {
3198 current_thread.endSyscall();3180 current_thread.endSyscall();
3199 switch (e) {3181 switch (e) {
...@@ -3291,11 +3273,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr...@@ -3291,11 +3273,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
3291 current_thread.endSyscall();3273 current_thread.endSyscall();
3292 return;3274 return;
3293 },3275 },
3294 .INTR => {3276 .INTR, .CANCELED => {
3295 try current_thread.checkCancel();3277 try current_thread.checkCancel();
3296 continue;3278 continue;
3297 },3279 },
3298 .CANCELED => return current_thread.endSyscallCanceled(),
3299 else => |e| {3280 else => |e| {
3300 current_thread.endSyscall();3281 current_thread.endSyscall();
3301 switch (e) {3282 switch (e) {
...@@ -3324,11 +3305,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr...@@ -3324,11 +3305,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
3324 current_thread.endSyscall();3305 current_thread.endSyscall();
3325 return;3306 return;
3326 },3307 },
3327 .INTR => {3308 .INTR, .CANCELED => {
3328 try current_thread.checkCancel();3309 try current_thread.checkCancel();
3329 continue;3310 continue;
3330 },3311 },
3331 .CANCELED => return current_thread.endSyscallCanceled(),
3332 else => |e| {3312 else => |e| {
3333 current_thread.endSyscall();3313 current_thread.endSyscall();
3334 switch (e) {3314 switch (e) {
...@@ -3353,11 +3333,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr...@@ -3353,11 +3333,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
3353 current_thread.endSyscall();3333 current_thread.endSyscall();
3354 return;3334 return;
3355 },3335 },
3356 .INTR => {3336 .INTR, .CANCELED => {
3357 try current_thread.checkCancel();3337 try current_thread.checkCancel();
3358 continue;3338 continue;
3359 },3339 },
3360 .CANCELED => return current_thread.endSyscallCanceled(),
3361 else => |e| {3340 else => |e| {
3362 current_thread.endSyscall();3341 current_thread.endSyscall();
3363 switch (e) {3342 switch (e) {
...@@ -3510,11 +3489,10 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -3510,11 +3489,10 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
3510 current_thread.endSyscall();3489 current_thread.endSyscall();
3511 return;3490 return;
3512 },3491 },
3513 .INTR => {3492 .INTR, .CANCELED => {
3514 try current_thread.checkCancel();3493 try current_thread.checkCancel();
3515 continue;3494 continue;
3516 },3495 },
3517 .CANCELED => return current_thread.endSyscallCanceled(),
3518 else => |e| {3496 else => |e| {
3519 current_thread.endSyscall();3497 current_thread.endSyscall();
3520 switch (e) {3498 switch (e) {
...@@ -3588,11 +3566,10 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -3588,11 +3566,10 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
3588 try current_thread.beginSyscall();3566 try current_thread.beginSyscall();
3589 while (true) {3567 while (true) {
3590 switch (posix.errno(posix.system.nanosleep(&timespec, &timespec))) {3568 switch (posix.errno(posix.system.nanosleep(&timespec, &timespec))) {
3591 .INTR => {3569 .INTR, .CANCELED => {
3592 try current_thread.checkCancel();3570 try current_thread.checkCancel();
3593 continue;3571 continue;
3594 },3572 },
3595 .CANCELED => return current_thread.endSyscallCanceled(),
3596 // This prong handles success as well as unexpected errors.3573 // This prong handles success as well as unexpected errors.
3597 else => return current_thread.endSyscall(),3574 else => return current_thread.endSyscall(),
3598 }3575 }
...@@ -3662,11 +3639,10 @@ fn netListenIpPosix(...@@ -3662,11 +3639,10 @@ fn netListenIpPosix(
3662 current_thread.endSyscall();3639 current_thread.endSyscall();
3663 break;3640 break;
3664 },3641 },
3665 .INTR => {3642 .INTR, .CANCELED => {
3666 try current_thread.checkCancel();3643 try current_thread.checkCancel();
3667 continue;3644 continue;
3668 },3645 },
3669 .CANCELED => return current_thread.endSyscallCanceled(),
3670 else => |e| {3646 else => |e| {
3671 current_thread.endSyscall();3647 current_thread.endSyscall();
3672 switch (e) {3648 switch (e) {
...@@ -3711,7 +3687,10 @@ fn netListenIpWindows(...@@ -3711,7 +3687,10 @@ fn netListenIpWindows(
3711 try current_thread.beginSyscall();3687 try current_thread.beginSyscall();
3712 while (true) {3688 while (true) {
3713 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);3689 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
3714 if (rc != ws2_32.SOCKET_ERROR) break;3690 if (rc != ws2_32.SOCKET_ERROR) {
3691 current_thread.endSyscall();
3692 break;
3693 }
3715 switch (ws2_32.WSAGetLastError()) {3694 switch (ws2_32.WSAGetLastError()) {
3716 .EINTR => {3695 .EINTR => {
3717 try current_thread.checkCancel();3696 try current_thread.checkCancel();
...@@ -3739,7 +3718,7 @@ fn netListenIpWindows(...@@ -3739,7 +3718,7 @@ fn netListenIpWindows(
3739 }3718 }
3740 }3719 }
37413720
3742 try current_thread.checkCancel();3721 try current_thread.beginSyscall();
3743 while (true) {3722 while (true) {
3744 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);3723 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);
3745 if (rc != ws2_32.SOCKET_ERROR) {3724 if (rc != ws2_32.SOCKET_ERROR) {
...@@ -3823,11 +3802,10 @@ fn netListenUnixPosix(...@@ -3823,11 +3802,10 @@ fn netListenUnixPosix(
3823 current_thread.endSyscall();3802 current_thread.endSyscall();
3824 break;3803 break;
3825 },3804 },
3826 .INTR => {3805 .INTR, .CANCELED => {
3827 try current_thread.checkCancel();3806 try current_thread.checkCancel();
3828 continue;3807 continue;
3829 },3808 },
3830 .CANCELED => return current_thread.endSyscallCanceled(),
3831 else => |e| {3809 else => |e| {
3832 current_thread.endSyscall();3810 current_thread.endSyscall();
3833 switch (e) {3811 switch (e) {
...@@ -3947,11 +3925,10 @@ fn posixBindUnix(...@@ -3947,11 +3925,10 @@ fn posixBindUnix(
3947 current_thread.endSyscall();3925 current_thread.endSyscall();
3948 break;3926 break;
3949 },3927 },
3950 .INTR => {3928 .INTR, .CANCELED => {
3951 try current_thread.checkCancel();3929 try current_thread.checkCancel();
3952 continue;3930 continue;
3953 },3931 },
3954 .CANCELED => return current_thread.endSyscallCanceled(),
3955 else => |e| {3932 else => |e| {
3956 current_thread.endSyscall();3933 current_thread.endSyscall();
3957 switch (e) {3934 switch (e) {
...@@ -3992,11 +3969,10 @@ fn posixBind(...@@ -3992,11 +3969,10 @@ fn posixBind(
3992 current_thread.endSyscall();3969 current_thread.endSyscall();
3993 break;3970 break;
3994 },3971 },
3995 .INTR => {3972 .INTR, .CANCELED => {
3996 try current_thread.checkCancel();3973 try current_thread.checkCancel();
3997 continue;3974 continue;
3998 },3975 },
3999 .CANCELED => return current_thread.endSyscallCanceled(),
4000 else => |e| {3976 else => |e| {
4001 current_thread.endSyscall();3977 current_thread.endSyscall();
4002 switch (e) {3978 switch (e) {
...@@ -4028,11 +4004,10 @@ fn posixConnect(...@@ -4028,11 +4004,10 @@ fn posixConnect(
4028 current_thread.endSyscall();4004 current_thread.endSyscall();
4029 return;4005 return;
4030 },4006 },
4031 .INTR => {4007 .INTR, .CANCELED => {
4032 try current_thread.checkCancel();4008 try current_thread.checkCancel();
4033 continue;4009 continue;
4034 },4010 },
4035 .CANCELED => return current_thread.endSyscallCanceled(),
4036 else => |e| {4011 else => |e| {
4037 current_thread.endSyscall();4012 current_thread.endSyscall();
4038 switch (e) {4013 switch (e) {
...@@ -4075,11 +4050,10 @@ fn posixConnectUnix(...@@ -4075,11 +4050,10 @@ fn posixConnectUnix(
4075 current_thread.endSyscall();4050 current_thread.endSyscall();
4076 return;4051 return;
4077 },4052 },
4078 .INTR => {4053 .INTR, .CANCELED => {
4079 try current_thread.checkCancel();4054 try current_thread.checkCancel();
4080 continue;4055 continue;
4081 },4056 },
4082 .CANCELED => return current_thread.endSyscallCanceled(),
4083 else => |e| {4057 else => |e| {
4084 current_thread.endSyscall();4058 current_thread.endSyscall();
4085 switch (e) {4059 switch (e) {
...@@ -4120,11 +4094,10 @@ fn posixGetSockName(...@@ -4120,11 +4094,10 @@ fn posixGetSockName(
4120 current_thread.endSyscall();4094 current_thread.endSyscall();
4121 break;4095 break;
4122 },4096 },
4123 .INTR => {4097 .INTR, .CANCELED => {
4124 try current_thread.checkCancel();4098 try current_thread.checkCancel();
4125 continue;4099 continue;
4126 },4100 },
4127 .CANCELED => return current_thread.endSyscallCanceled(),
4128 else => |e| {4101 else => |e| {
4129 current_thread.endSyscall();4102 current_thread.endSyscall();
4130 switch (e) {4103 switch (e) {
...@@ -4188,11 +4161,10 @@ fn setSocketOption(current_thread: *Thread, fd: posix.fd_t, level: i32, opt_name...@@ -4188,11 +4161,10 @@ fn setSocketOption(current_thread: *Thread, fd: posix.fd_t, level: i32, opt_name
4188 current_thread.endSyscall();4161 current_thread.endSyscall();
4189 return;4162 return;
4190 },4163 },
4191 .INTR => {4164 .INTR, .CANCELED => {
4192 try current_thread.checkCancel();4165 try current_thread.checkCancel();
4193 continue;4166 continue;
4194 },4167 },
4195 .CANCELED => return current_thread.endSyscallCanceled(),
4196 else => |e| {4168 else => |e| {
4197 current_thread.endSyscall();4169 current_thread.endSyscall();
4198 switch (e) {4170 switch (e) {
...@@ -4521,8 +4493,7 @@ fn openSocketPosix(...@@ -4521,8 +4493,7 @@ fn openSocketPosix(
4521 try current_thread.checkCancel();4493 try current_thread.checkCancel();
4522 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {4494 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
4523 .SUCCESS => break,4495 .SUCCESS => break,
4524 .INTR => continue,4496 .INTR, .CANCELED => continue,
4525 .CANCELED => return current_thread.endSyscallCanceled(),
4526 else => |err| {4497 else => |err| {
4527 current_thread.endSyscall();4498 current_thread.endSyscall();
4528 return posix.unexpectedErrno(err);4499 return posix.unexpectedErrno(err);
...@@ -4532,11 +4503,10 @@ fn openSocketPosix(...@@ -4532,11 +4503,10 @@ fn openSocketPosix(
4532 current_thread.endSyscall();4503 current_thread.endSyscall();
4533 break fd;4504 break fd;
4534 },4505 },
4535 .INTR => {4506 .INTR, .CANCELED => {
4536 try current_thread.checkCancel();4507 try current_thread.checkCancel();
4537 continue;4508 continue;
4538 },4509 },
4539 .CANCELED => return current_thread.endSyscallCanceled(),
4540 else => |e| {4510 else => |e| {
4541 current_thread.endSyscall();4511 current_thread.endSyscall();
4542 switch (e) {4512 switch (e) {
...@@ -4624,7 +4594,7 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve...@@ -4624,7 +4594,7 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
4624 try current_thread.checkCancel();4594 try current_thread.checkCancel();
4625 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {4595 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
4626 .SUCCESS => break,4596 .SUCCESS => break,
4627 .INTR => continue,4597 .INTR, .CANCELED => continue,
4628 else => |err| {4598 else => |err| {
4629 current_thread.endSyscall();4599 current_thread.endSyscall();
4630 return posix.unexpectedErrno(err);4600 return posix.unexpectedErrno(err);
...@@ -4634,11 +4604,10 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve...@@ -4634,11 +4604,10 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
4634 current_thread.endSyscall();4604 current_thread.endSyscall();
4635 break fd;4605 break fd;
4636 },4606 },
4637 .INTR => {4607 .INTR, .CANCELED => {
4638 try current_thread.checkCancel();4608 try current_thread.checkCancel();
4639 continue;4609 continue;
4640 },4610 },
4641 .CANCELED => return current_thread.endSyscallCanceled(),
4642 else => |e| {4611 else => |e| {
4643 current_thread.endSyscall();4612 current_thread.endSyscall();
4644 switch (e) {4613 switch (e) {
...@@ -4743,11 +4712,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -4743,11 +4712,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
4743 current_thread.endSyscall();4712 current_thread.endSyscall();
4744 return n;4713 return n;
4745 },4714 },
4746 .INTR => {4715 .INTR, .CANCELED => {
4747 try current_thread.checkCancel();4716 try current_thread.checkCancel();
4748 continue;4717 continue;
4749 },4718 },
4750 .CANCELED => return current_thread.endSyscallCanceled(),
4751 else => |e| {4719 else => |e| {
4752 current_thread.endSyscall();4720 current_thread.endSyscall();
4753 switch (e) {4721 switch (e) {
...@@ -4776,11 +4744,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -4776,11 +4744,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
4776 current_thread.endSyscall();4744 current_thread.endSyscall();
4777 return @intCast(rc);4745 return @intCast(rc);
4778 },4746 },
4779 .INTR => {4747 .INTR, .CANCELED => {
4780 try current_thread.checkCancel();4748 try current_thread.checkCancel();
4781 continue;4749 continue;
4782 },4750 },
4783 .CANCELED => return current_thread.endSyscallCanceled(),
4784 else => |e| {4751 else => |e| {
4785 current_thread.endSyscall();4752 current_thread.endSyscall();
4786 switch (e) {4753 switch (e) {
...@@ -5012,11 +4979,10 @@ fn netSendOne(...@@ -5012,11 +4979,10 @@ fn netSendOne(
5012 message.data_len = @intCast(rc);4979 message.data_len = @intCast(rc);
5013 return;4980 return;
5014 },4981 },
5015 .INTR => {4982 .INTR, .CANCELED => {
5016 try current_thread.checkCancel();4983 try current_thread.checkCancel();
5017 continue;4984 continue;
5018 },4985 },
5019 .CANCELED => return current_thread.endSyscallCanceled(),
5020 else => |e| {4986 else => |e| {
5021 current_thread.endSyscall();4987 current_thread.endSyscall();
5022 switch (e) {4988 switch (e) {
...@@ -5089,11 +5055,10 @@ fn netSendMany(...@@ -5089,11 +5055,10 @@ fn netSendMany(
5089 }5055 }
5090 return n;5056 return n;
5091 },5057 },
5092 .INTR => {5058 .INTR, .CANCELED => {
5093 try current_thread.checkCancel();5059 try current_thread.checkCancel();
5094 continue;5060 continue;
5095 },5061 },
5096 .CANCELED => return current_thread.endSyscallCanceled(),
5097 else => |e| {5062 else => |e| {
5098 current_thread.endSyscall();5063 current_thread.endSyscall();
5099 switch (e) {5064 switch (e) {
...@@ -5225,8 +5190,7 @@ fn netReceivePosix(...@@ -5225,8 +5190,7 @@ fn netReceivePosix(
5225 }5190 }
5226 continue :recv;5191 continue :recv;
5227 },5192 },
5228 .INTR => continue,5193 .INTR, .CANCELED => continue,
5229 .CANCELED => return .{ current_thread.endSyscallCanceled(), message_i },
52305194
5231 .FAULT => |err| return .{ errnoBug(err), message_i },5195 .FAULT => |err| return .{ errnoBug(err), message_i },
5232 .INVAL => |err| return .{ errnoBug(err), message_i },5196 .INVAL => |err| return .{ errnoBug(err), message_i },
...@@ -5234,8 +5198,7 @@ fn netReceivePosix(...@@ -5234,8 +5198,7 @@ fn netReceivePosix(
5234 else => |err| return .{ posix.unexpectedErrno(err), message_i },5198 else => |err| return .{ posix.unexpectedErrno(err), message_i },
5235 }5199 }
5236 },5200 },
5237 .INTR => continue,5201 .INTR, .CANCELED => continue,
5238 .CANCELED => return .{ current_thread.endSyscallCanceled(), message_i },
52395202
5240 .BADF => |err| return .{ errnoBug(err), message_i },5203 .BADF => |err| return .{ errnoBug(err), message_i },
5241 .NFILE => return .{ error.SystemFdQuotaExceeded, message_i },5204 .NFILE => return .{ error.SystemFdQuotaExceeded, message_i },
...@@ -5350,11 +5313,10 @@ fn netWritePosix(...@@ -5350,11 +5313,10 @@ fn netWritePosix(
5350 current_thread.endSyscall();5313 current_thread.endSyscall();
5351 return @intCast(rc);5314 return @intCast(rc);
5352 },5315 },
5353 .INTR => {5316 .INTR, .CANCELED => {
5354 try current_thread.checkCancel();5317 try current_thread.checkCancel();
5355 continue;5318 continue;
5356 },5319 },
5357 .CANCELED => return current_thread.endSyscallCanceled(),
5358 else => |e| {5320 else => |e| {
5359 current_thread.endSyscall();5321 current_thread.endSyscall();
5360 switch (e) {5322 switch (e) {
...@@ -5452,8 +5414,7 @@ fn netWriteWindows(...@@ -5452,8 +5414,7 @@ fn netWriteWindows(
5452 else => |err| err,5414 else => |err| err,
5453 };5415 };
5454 switch (wsa_error) {5416 switch (wsa_error) {
5455 .EINTR => continue,5417 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => continue,
5456 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return current_thread.endSyscallCanceled(),
5457 .NOTINITIALISED => {5418 .NOTINITIALISED => {
5458 try initializeWsa(t);5419 try initializeWsa(t);
5459 continue;5420 continue;
...@@ -5561,11 +5522,10 @@ fn netInterfaceNameResolve(...@@ -5561,11 +5522,10 @@ fn netInterfaceNameResolve(
5561 current_thread.endSyscall();5522 current_thread.endSyscall();
5562 return .{ .index = @bitCast(ifr.ifru.ivalue) };5523 return .{ .index = @bitCast(ifr.ifru.ivalue) };
5563 },5524 },
5564 .INTR => {5525 .INTR, .CANCELED => {
5565 try current_thread.checkCancel();5526 try current_thread.checkCancel();
5566 continue;5527 continue;
5567 },5528 },
5568 .CANCELED => return current_thread.endSyscallCanceled(),
5569 else => |e| {5529 else => |e| {
5570 current_thread.endSyscall();5530 current_thread.endSyscall();
5571 switch (e) {5531 switch (e) {
...@@ -5862,11 +5822,10 @@ fn netLookupFallible(...@@ -5862,11 +5822,10 @@ fn netLookupFallible(
5862 break;5822 break;
5863 },5823 },
5864 .SYSTEM => switch (posix.errno(-1)) {5824 .SYSTEM => switch (posix.errno(-1)) {
5865 .INTR => {5825 .INTR, .CANCELED => {
5866 try current_thread.checkCancel();5826 try current_thread.checkCancel();
5867 continue;5827 continue;
5868 },5828 },
5869 .CANCELED => return current_thread.endSyscallCanceled(),
5870 else => |e| {5829 else => |e| {
5871 current_thread.endSyscall();5830 current_thread.endSyscall();
5872 return posix.unexpectedErrno(e);5831 return posix.unexpectedErrno(e);
...@@ -6612,15 +6571,15 @@ fn futexWait(current_thread: *Thread, ptr: *const std.atomic.Value(u32), expect:...@@ -6612,15 +6571,15 @@ fn futexWait(current_thread: *Thread, ptr: *const std.atomic.Value(u32), expect:
6612 try current_thread.beginSyscall();6571 try current_thread.beginSyscall();
6613 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);6572 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);
6614 current_thread.endSyscall();6573 current_thread.endSyscall();
6615 if (is_debug) switch (linux.errno(rc)) {6574 switch (linux.errno(rc)) {
6616 .SUCCESS => {}, // notified by `wake()`6575 .SUCCESS => {}, // notified by `wake()`
6617 .INTR => {}, // gives caller a chance to check cancellation6576 .INTR => {}, // caller's responsibility to retry
6618 .AGAIN => {}, // ptr.* != expect6577 .AGAIN => {}, // ptr.* != expect
6619 .INVAL => {}, // possibly timeout overflow6578 .INVAL => {}, // possibly timeout overflow
6620 .TIMEDOUT => unreachable,6579 .TIMEDOUT => recoverableOsBugDetected(),
6621 .FAULT => unreachable, // ptr was invalid6580 .FAULT => recoverableOsBugDetected(), // ptr was invalid
6622 else => unreachable,6581 else => recoverableOsBugDetected(),
6623 };6582 }
6624 },6583 },
6625 .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => {6584 .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => {
6626 const c = std.c;6585 const c = std.c;
...@@ -6703,7 +6662,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi...@@ -6703,7 +6662,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
6703 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);6662 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);
6704 switch (linux.errno(rc)) {6663 switch (linux.errno(rc)) {
6705 .SUCCESS => {}, // notified by `wake()`6664 .SUCCESS => {}, // notified by `wake()`
6706 .INTR => {}, // gives caller a chance to check cancellation6665 .INTR => {}, // caller's responsibility to repeat
6707 .AGAIN => {}, // ptr.* != expect6666 .AGAIN => {}, // ptr.* != expect
6708 .INVAL => {}, // possibly timeout overflow6667 .INVAL => {}, // possibly timeout overflow
6709 .TIMEDOUT => recoverableOsBugDetected(),6668 .TIMEDOUT => recoverableOsBugDetected(),
...@@ -6757,28 +6716,6 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi...@@ -6757,28 +6716,6 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
6757 }6716 }
6758}6717}
67596718
6760pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect: u32, timeout: Io.Duration) void {
6761 @branchHint(.cold);
6762
6763 if (native_os == .linux) {
6764 const linux = std.os.linux;
6765 var ts = timestampToPosix(timeout.toNanoseconds());
6766 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, &ts);
6767 if (is_debug) switch (linux.errno(rc)) {
6768 .SUCCESS => {}, // notified by `wake()`
6769 .INTR => {}, // gives caller a chance to check cancellation
6770 .AGAIN => {}, // ptr.* != expect
6771 .TIMEDOUT => {},
6772 .INVAL => {}, // possibly timeout overflow
6773 .FAULT => unreachable, // ptr was invalid
6774 else => unreachable,
6775 };
6776 return;
6777 } else {
6778 @compileError("TODO");
6779 }
6780}
6781
6782pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {6719pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
6783 @branchHint(.cold);6720 @branchHint(.cold);
67846721