authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-11-29 07:36:44-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-01 19:17:52-08:00
log39ac40209b57d105dff28988a954a594e2e9dd8f
tree12529825088f0ef1aaedf659d4118ef63a4b9c3a
parentd60760d61e19018aa354fbb2f241444db88ca51b

std.Io.Threaded: use musl's beautiful pthread_cancel semantics


3 files changed, 121 insertions(+), 83 deletions(-)

lib/std/Io/Threaded.zig+103-83
...@@ -3,6 +3,7 @@ const Threaded = @This();...@@ -3,6 +3,7 @@ const Threaded = @This();
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const native_os = builtin.os.tag;4const native_os = builtin.os.tag;
5const is_windows = native_os == .windows;5const is_windows = native_os == .windows;
6const is_musl = builtin.link_libc and builtin.abi.isMusl();
6const windows = std.os.windows;7const windows = std.os.windows;
7const ws2_32 = std.os.windows.ws2_32;8const ws2_32 = std.os.windows.ws2_32;
8const is_debug = builtin.mode == .Debug;9const is_debug = builtin.mode == .Debug;
...@@ -111,7 +112,7 @@ const Thread = struct {...@@ -111,7 +112,7 @@ const Thread = struct {
111 @atomicStore(CancelStatus, &closure.cancel_status, .acknowledged, .release);112 @atomicStore(CancelStatus, &closure.cancel_status, .acknowledged, .release);
112 return error.Canceled;113 return error.Canceled;
113 },114 },
114 .acknowledged => unreachable,115 .acknowledged => return,
115 _ => unreachable,116 _ => unreachable,
116 }117 }
117 }118 }
...@@ -128,6 +129,13 @@ const Thread = struct {...@@ -128,6 +129,13 @@ const Thread = struct {
128 );129 );
129 }130 }
130131
132 fn endSyscallCanceled(thread: *Thread) Io.Cancelable {
133 if (thread.current_closure) |closure| {
134 @atomicStore(CancelStatus, &closure.cancel_status, .acknowledged, .release);
135 }
136 return error.Canceled;
137 }
138
131 fn currentSignalId() SignalId {139 fn currentSignalId() SignalId {
132 return if (std.Thread.use_pthreads) std.c.pthread_self() else std.Thread.getCurrentId();140 return if (std.Thread.use_pthreads) std.c.pthread_self() else std.Thread.getCurrentId();
133 }141 }
...@@ -197,6 +205,13 @@ const Closure = struct {...@@ -197,6 +205,13 @@ const Closure = struct {
197 .none, .acknowledged, .requested => return,205 .none, .acknowledged, .requested => return,
198 .signal_id => |signal_id| signal_id,206 .signal_id => |signal_id| signal_id,
199 };207 };
208 // Musl has an undocumented extension that makes pthread_cancel have the useful, desired
209 // behavior of causing the next syscall to return ECANCELED.
210 if (is_musl) {
211 _ = std.c.pthread_cancel(signal_id);
212 return;
213 }
214
200 // The task will enter a blocking syscall before checking for cancellation again.215 // The task will enter a blocking syscall before checking for cancellation again.
201 // We can send a signal to interrupt the syscall, but if it arrives before216 // We can send a signal to interrupt the syscall, but if it arrives before
202 // the syscall instruction, it will be missed. Therefore, this code tries217 // the syscall instruction, it will be missed. Therefore, this code tries
...@@ -218,8 +233,7 @@ const Closure = struct {...@@ -218,8 +233,7 @@ const Closure = struct {
218233
219 for (0..max_attempts) |attempt_index| {234 for (0..max_attempts) |attempt_index| {
220 if (std.Thread.use_pthreads) {235 if (std.Thread.use_pthreads) {
221 const rc = std.c.pthread_kill(signal_id, .IO);236 if (std.c.pthread_kill(signal_id, .IO) != 0) return;
222 if (is_debug) assert(rc == 0);
223 } else if (native_os == .linux) {237 } else if (native_os == .linux) {
224 const pid: posix.pid_t = p: {238 const pid: posix.pid_t = p: {
225 const cached_pid = @atomicLoad(Pid, &t.pid, .monotonic);239 const cached_pid = @atomicLoad(Pid, &t.pid, .monotonic);
...@@ -228,7 +242,7 @@ const Closure = struct {...@@ -228,7 +242,7 @@ const Closure = struct {
228 @atomicStore(Pid, &t.pid, @enumFromInt(pid), .monotonic);242 @atomicStore(Pid, &t.pid, @enumFromInt(pid), .monotonic);
229 break :p pid;243 break :p pid;
230 };244 };
231 _ = std.os.linux.tgkill(pid, @bitCast(signal_id), .IO);245 if (std.os.linux.tgkill(pid, @bitCast(signal_id), .IO) != 0) return;
232 } else {246 } else {
233 return;247 return;
234 }248 }
...@@ -354,6 +368,11 @@ fn worker(t: *Threaded) void {...@@ -354,6 +368,11 @@ fn worker(t: *Threaded) void {
354 while (true) {368 while (true) {
355 while (t.run_queue.popFirst()) |closure_node| {369 while (t.run_queue.popFirst()) |closure_node| {
356 t.mutex.unlock();370 t.mutex.unlock();
371
372 // Musl has an undocumented extension that makes pthread_cancel have the useful, desired
373 // behavior of causing the next syscall to return ECANCELED.
374 if (is_musl) assert(std.c.pthread_setcancelstate(.MASKED, null) == .SUCCESS);
375
357 const closure: *Closure = @fieldParentPtr("node", closure_node);376 const closure: *Closure = @fieldParentPtr("node", closure_node);
358 closure.start(closure, t);377 closure.start(closure, t);
359 t.mutex.lock();378 t.mutex.lock();
...@@ -1198,10 +1217,10 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:...@@ -1198,10 +1217,10 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:
1198 try current_thread.checkCancel();1217 try current_thread.checkCancel();
1199 continue;1218 continue;
1200 },1219 },
1220 .CANCELED => return current_thread.endSyscallCanceled(),
1201 else => |e| {1221 else => |e| {
1202 current_thread.endSyscall();1222 current_thread.endSyscall();
1203 switch (e) {1223 switch (e) {
1204 .CANCELED => return error.Canceled,
1205 .ACCES => return error.AccessDenied,1224 .ACCES => return error.AccessDenied,
1206 .BADF => |err| return errnoBug(err), // File descriptor used after closed.1225 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1207 .PERM => return error.PermissionDenied,1226 .PERM => return error.PermissionDenied,
...@@ -1241,25 +1260,29 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: I...@@ -1241,25 +1260,29 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: I
1241 try current_thread.checkCancel();1260 try current_thread.checkCancel();
1242 continue;1261 continue;
1243 },1262 },
1244 .CANCELED => return error.Canceled,1263 .CANCELED => return current_thread.endSyscallCanceled(),
12451264 else => |e| {
1246 .ACCES => return error.AccessDenied,1265 current_thread.endSyscall();
1247 .BADF => |err| return errnoBug(err), // File descriptor used after closed.1266 switch (e) {
1248 .PERM => return error.PermissionDenied,1267 .ACCES => return error.AccessDenied,
1249 .DQUOT => return error.DiskQuota,1268 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1250 .EXIST => return error.PathAlreadyExists,1269 .PERM => return error.PermissionDenied,
1251 .FAULT => |err| return errnoBug(err),1270 .DQUOT => return error.DiskQuota,
1252 .LOOP => return error.SymLinkLoop,1271 .EXIST => return error.PathAlreadyExists,
1253 .MLINK => return error.LinkQuotaExceeded,1272 .FAULT => |err| return errnoBug(err),
1254 .NAMETOOLONG => return error.NameTooLong,1273 .LOOP => return error.SymLinkLoop,
1255 .NOENT => return error.FileNotFound,1274 .MLINK => return error.LinkQuotaExceeded,
1256 .NOMEM => return error.SystemResources,1275 .NAMETOOLONG => return error.NameTooLong,
1257 .NOSPC => return error.NoSpaceLeft,1276 .NOENT => return error.FileNotFound,
1258 .NOTDIR => return error.NotDir,1277 .NOMEM => return error.SystemResources,
1259 .ROFS => return error.ReadOnlyFileSystem,1278 .NOSPC => return error.NoSpaceLeft,
1260 .NOTCAPABLE => return error.AccessDenied,1279 .NOTDIR => return error.NotDir,
1261 .ILSEQ => return error.BadPathName,1280 .ROFS => return error.ReadOnlyFileSystem,
1262 else => |err| return posix.unexpectedErrno(err),1281 .NOTCAPABLE => return error.AccessDenied,
1282 .ILSEQ => return error.BadPathName,
1283 else => |err| return posix.unexpectedErrno(err),
1284 }
1285 },
1263 }1286 }
1264 }1287 }
1265}1288}
...@@ -1503,10 +1526,10 @@ fn dirStatPathLinux(...@@ -1503,10 +1526,10 @@ fn dirStatPathLinux(
1503 try current_thread.checkCancel();1526 try current_thread.checkCancel();
1504 continue;1527 continue;
1505 },1528 },
1529 .CANCELED => return current_thread.endSyscallCanceled(),
1506 else => |e| {1530 else => |e| {
1507 current_thread.endSyscall();1531 current_thread.endSyscall();
1508 switch (e) {1532 switch (e) {
1509 .CANCELED => return error.Canceled,
1510 .ACCES => return error.AccessDenied,1533 .ACCES => return error.AccessDenied,
1511 .BADF => |err| return errnoBug(err), // File descriptor used after closed.1534 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1512 .FAULT => |err| return errnoBug(err),1535 .FAULT => |err| return errnoBug(err),
...@@ -1549,10 +1572,10 @@ fn dirStatPathPosix(...@@ -1549,10 +1572,10 @@ fn dirStatPathPosix(
1549 try current_thread.checkCancel();1572 try current_thread.checkCancel();
1550 continue;1573 continue;
1551 },1574 },
1575 .CANCELED => return current_thread.endSyscallCanceled(),
1552 else => |e| {1576 else => |e| {
1553 current_thread.endSyscall();1577 current_thread.endSyscall();
1554 switch (e) {1578 switch (e) {
1555 .CANCELED => return error.Canceled,
1556 .INVAL => |err| return errnoBug(err),1579 .INVAL => |err| return errnoBug(err),
1557 .BADF => |err| return errnoBug(err), // File descriptor used after closed.1580 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1558 .NOMEM => return error.SystemResources,1581 .NOMEM => return error.SystemResources,
...@@ -1610,10 +1633,10 @@ fn dirStatPathWasi(...@@ -1610,10 +1633,10 @@ fn dirStatPathWasi(
1610 try current_thread.checkCancel();1633 try current_thread.checkCancel();
1611 continue;1634 continue;
1612 },1635 },
1636 .CANCELED => return current_thread.endSyscallCanceled(),
1613 else => |e| {1637 else => |e| {
1614 current_thread.endSyscall();1638 current_thread.endSyscall();
1615 switch (e) {1639 switch (e) {
1616 .CANCELED => return error.Canceled,
1617 .INVAL => |err| return errnoBug(err),1640 .INVAL => |err| return errnoBug(err),
1618 .BADF => |err| return errnoBug(err), // File descriptor used after closed.1641 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1619 .NOMEM => return error.SystemResources,1642 .NOMEM => return error.SystemResources,
...@@ -1656,10 +1679,10 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File...@@ -1656,10 +1679,10 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
1656 try current_thread.checkCancel();1679 try current_thread.checkCancel();
1657 continue;1680 continue;
1658 },1681 },
1682 .CANCELED => return current_thread.endSyscallCanceled(),
1659 else => |e| {1683 else => |e| {
1660 current_thread.endSyscall();1684 current_thread.endSyscall();
1661 switch (e) {1685 switch (e) {
1662 .CANCELED => return error.Canceled,
1663 .INVAL => |err| return errnoBug(err),1686 .INVAL => |err| return errnoBug(err),
1664 .BADF => |err| return errnoBug(err), // File descriptor used after closed.1687 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1665 .NOMEM => return error.SystemResources,1688 .NOMEM => return error.SystemResources,
...@@ -1695,10 +1718,10 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File...@@ -1695,10 +1718,10 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
1695 try current_thread.checkCancel();1718 try current_thread.checkCancel();
1696 continue;1719 continue;
1697 },1720 },
1721 .CANCELED => return current_thread.endSyscallCanceled(),
1698 else => |e| {1722 else => |e| {
1699 current_thread.endSyscall();1723 current_thread.endSyscall();
1700 switch (e) {1724 switch (e) {
1701 .CANCELED => return error.Canceled,
1702 .ACCES => |err| return errnoBug(err),1725 .ACCES => |err| return errnoBug(err),
1703 .BADF => |err| return errnoBug(err), // File descriptor used after closed.1726 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1704 .FAULT => |err| return errnoBug(err),1727 .FAULT => |err| return errnoBug(err),
...@@ -1781,10 +1804,10 @@ fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File....@@ -1781,10 +1804,10 @@ fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.
1781 try current_thread.checkCancel();1804 try current_thread.checkCancel();
1782 continue;1805 continue;
1783 },1806 },
1807 .CANCELED => return current_thread.endSyscallCanceled(),
1784 else => |e| {1808 else => |e| {
1785 current_thread.endSyscall();1809 current_thread.endSyscall();
1786 switch (e) {1810 switch (e) {
1787 .CANCELED => return error.Canceled,
1788 .INVAL => |err| return errnoBug(err),1811 .INVAL => |err| return errnoBug(err),
1789 .BADF => |err| return errnoBug(err), // File descriptor used after closed.1812 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1790 .NOMEM => return error.SystemResources,1813 .NOMEM => return error.SystemResources,
...@@ -1833,10 +1856,10 @@ fn dirAccessPosix(...@@ -1833,10 +1856,10 @@ fn dirAccessPosix(
1833 try current_thread.checkCancel();1856 try current_thread.checkCancel();
1834 continue;1857 continue;
1835 },1858 },
1859 .CANCELED => return current_thread.endSyscallCanceled(),
1836 else => |e| {1860 else => |e| {
1837 current_thread.endSyscall();1861 current_thread.endSyscall();
1838 switch (e) {1862 switch (e) {
1839 .CANCELED => return error.Canceled,
1840 .ACCES => return error.AccessDenied,1863 .ACCES => return error.AccessDenied,
1841 .PERM => return error.PermissionDenied,1864 .PERM => return error.PermissionDenied,
1842 .ROFS => return error.ReadOnlyFileSystem,1865 .ROFS => return error.ReadOnlyFileSystem,
...@@ -1883,10 +1906,10 @@ fn dirAccessWasi(...@@ -1883,10 +1906,10 @@ fn dirAccessWasi(
1883 try current_thread.checkCancel();1906 try current_thread.checkCancel();
1884 continue;1907 continue;
1885 },1908 },
1909 .CANCELED => return current_thread.endSyscallCanceled(),
1886 else => |e| {1910 else => |e| {
1887 current_thread.endSyscall();1911 current_thread.endSyscall();
1888 switch (e) {1912 switch (e) {
1889 .CANCELED => return error.Canceled,
1890 .INVAL => |err| return errnoBug(err),1913 .INVAL => |err| return errnoBug(err),
1891 .BADF => |err| return errnoBug(err), // File descriptor used after closed.1914 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1892 .NOMEM => return error.SystemResources,1915 .NOMEM => return error.SystemResources,
...@@ -2030,10 +2053,10 @@ fn dirCreateFilePosix(...@@ -2030,10 +2053,10 @@ fn dirCreateFilePosix(
2030 try current_thread.checkCancel();2053 try current_thread.checkCancel();
2031 continue;2054 continue;
2032 },2055 },
2056 .CANCELED => return current_thread.endSyscallCanceled(),
2033 else => |e| {2057 else => |e| {
2034 current_thread.endSyscall();2058 current_thread.endSyscall();
2035 switch (e) {2059 switch (e) {
2036 .CANCELED => return error.Canceled,
2037 .FAULT => |err| return errnoBug(err),2060 .FAULT => |err| return errnoBug(err),
2038 .INVAL => return error.BadPathName,2061 .INVAL => return error.BadPathName,
2039 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2062 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2085,10 +2108,10 @@ fn dirCreateFilePosix(...@@ -2085,10 +2108,10 @@ fn dirCreateFilePosix(
2085 try current_thread.checkCancel();2108 try current_thread.checkCancel();
2086 continue;2109 continue;
2087 },2110 },
2111 .CANCELED => return current_thread.endSyscallCanceled(),
2088 else => |e| {2112 else => |e| {
2089 current_thread.endSyscall();2113 current_thread.endSyscall();
2090 switch (e) {2114 switch (e) {
2091 .CANCELED => return error.Canceled,
2092 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2115 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
2093 .INVAL => |err| return errnoBug(err), // invalid parameters2116 .INVAL => |err| return errnoBug(err), // invalid parameters
2094 .NOLCK => return error.SystemResources,2117 .NOLCK => return error.SystemResources,
...@@ -2240,10 +2263,10 @@ fn dirCreateFileWasi(...@@ -2240,10 +2263,10 @@ fn dirCreateFileWasi(
2240 try current_thread.checkCancel();2263 try current_thread.checkCancel();
2241 continue;2264 continue;
2242 },2265 },
2266 .CANCELED => return current_thread.endSyscallCanceled(),
2243 else => |e| {2267 else => |e| {
2244 current_thread.endSyscall();2268 current_thread.endSyscall();
2245 switch (e) {2269 switch (e) {
2246 .CANCELED => return error.Canceled,
2247 .FAULT => |err| return errnoBug(err),2270 .FAULT => |err| return errnoBug(err),
2248 .INVAL => return error.BadPathName,2271 .INVAL => return error.BadPathName,
2249 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2272 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2334,10 +2357,10 @@ fn dirOpenFilePosix(...@@ -2334,10 +2357,10 @@ fn dirOpenFilePosix(
2334 try current_thread.checkCancel();2357 try current_thread.checkCancel();
2335 continue;2358 continue;
2336 },2359 },
2360 .CANCELED => return current_thread.endSyscallCanceled(),
2337 else => |e| {2361 else => |e| {
2338 current_thread.endSyscall();2362 current_thread.endSyscall();
2339 switch (e) {2363 switch (e) {
2340 .CANCELED => return error.Canceled,
2341 .FAULT => |err| return errnoBug(err),2364 .FAULT => |err| return errnoBug(err),
2342 .INVAL => return error.BadPathName,2365 .INVAL => return error.BadPathName,
2343 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2366 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2388,10 +2411,10 @@ fn dirOpenFilePosix(...@@ -2388,10 +2411,10 @@ fn dirOpenFilePosix(
2388 try current_thread.checkCancel();2411 try current_thread.checkCancel();
2389 continue;2412 continue;
2390 },2413 },
2414 .CANCELED => return current_thread.endSyscallCanceled(),
2391 else => |e| {2415 else => |e| {
2392 current_thread.endSyscall();2416 current_thread.endSyscall();
2393 switch (e) {2417 switch (e) {
2394 .CANCELED => return error.Canceled,
2395 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2418 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
2396 .INVAL => |err| return errnoBug(err), // invalid parameters2419 .INVAL => |err| return errnoBug(err), // invalid parameters
2397 .NOLCK => return error.SystemResources,2420 .NOLCK => return error.SystemResources,
...@@ -2417,6 +2440,7 @@ fn dirOpenFilePosix(...@@ -2417,6 +2440,7 @@ fn dirOpenFilePosix(
2417 try current_thread.checkCancel();2440 try current_thread.checkCancel();
2418 continue;2441 continue;
2419 },2442 },
2443 .CANCELED => return current_thread.endSyscallCanceled(),
2420 else => |err| {2444 else => |err| {
2421 current_thread.endSyscall();2445 current_thread.endSyscall();
2422 return posix.unexpectedErrno(err);2446 return posix.unexpectedErrno(err);
...@@ -2437,6 +2461,7 @@ fn dirOpenFilePosix(...@@ -2437,6 +2461,7 @@ fn dirOpenFilePosix(
2437 try current_thread.checkCancel();2461 try current_thread.checkCancel();
2438 continue;2462 continue;
2439 },2463 },
2464 .CANCELED => return current_thread.endSyscallCanceled(),
2440 else => |err| {2465 else => |err| {
2441 current_thread.endSyscall();2466 current_thread.endSyscall();
2442 return posix.unexpectedErrno(err);2467 return posix.unexpectedErrno(err);
...@@ -2635,10 +2660,10 @@ fn dirOpenFileWasi(...@@ -2635,10 +2660,10 @@ fn dirOpenFileWasi(
2635 try current_thread.checkCancel();2660 try current_thread.checkCancel();
2636 continue;2661 continue;
2637 },2662 },
2663 .CANCELED => return current_thread.endSyscallCanceled(),
2638 else => |e| {2664 else => |e| {
2639 current_thread.endSyscall();2665 current_thread.endSyscall();
2640 switch (e) {2666 switch (e) {
2641 .CANCELED => return error.Canceled,
2642 .FAULT => |err| return errnoBug(err),2667 .FAULT => |err| return errnoBug(err),
2643 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2668 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
2644 .ACCES => return error.AccessDenied,2669 .ACCES => return error.AccessDenied,
...@@ -2719,10 +2744,10 @@ fn dirOpenDirPosix(...@@ -2719,10 +2744,10 @@ fn dirOpenDirPosix(
2719 try current_thread.checkCancel();2744 try current_thread.checkCancel();
2720 continue;2745 continue;
2721 },2746 },
2747 .CANCELED => return current_thread.endSyscallCanceled(),
2722 else => |e| {2748 else => |e| {
2723 current_thread.endSyscall();2749 current_thread.endSyscall();
2724 switch (e) {2750 switch (e) {
2725 .CANCELED => return error.Canceled,
2726 .FAULT => |err| return errnoBug(err),2751 .FAULT => |err| return errnoBug(err),
2727 .INVAL => return error.BadPathName,2752 .INVAL => return error.BadPathName,
2728 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2753 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2772,10 +2797,10 @@ fn dirOpenDirHaiku(...@@ -2772,10 +2797,10 @@ fn dirOpenDirHaiku(
2772 try current_thread.checkCancel();2797 try current_thread.checkCancel();
2773 continue;2798 continue;
2774 },2799 },
2800 .CANCELED => return current_thread.endSyscallCanceled(),
2775 else => |e| {2801 else => |e| {
2776 current_thread.endSyscall();2802 current_thread.endSyscall();
2777 switch (e) {2803 switch (e) {
2778 .CANCELED => return error.Canceled,
2779 .FAULT => |err| return errnoBug(err),2804 .FAULT => |err| return errnoBug(err),
2780 .INVAL => |err| return errnoBug(err),2805 .INVAL => |err| return errnoBug(err),
2781 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2806 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2917,10 +2942,10 @@ fn dirOpenDirWasi(...@@ -2917,10 +2942,10 @@ fn dirOpenDirWasi(
2917 try current_thread.checkCancel();2942 try current_thread.checkCancel();
2918 continue;2943 continue;
2919 },2944 },
2945 .CANCELED => return current_thread.endSyscallCanceled(),
2920 else => |e| {2946 else => |e| {
2921 current_thread.endSyscall();2947 current_thread.endSyscall();
2922 switch (e) {2948 switch (e) {
2923 .CANCELED => return error.Canceled,
2924 .FAULT => |err| return errnoBug(err),2949 .FAULT => |err| return errnoBug(err),
2925 .INVAL => return error.BadPathName,2950 .INVAL => return error.BadPathName,
2926 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2951 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2984,10 +3009,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io...@@ -2984,10 +3009,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io
2984 try current_thread.checkCancel();3009 try current_thread.checkCancel();
2985 continue;3010 continue;
2986 },3011 },
3012 .CANCELED => return current_thread.endSyscallCanceled(),
2987 else => |e| {3013 else => |e| {
2988 current_thread.endSyscall();3014 current_thread.endSyscall();
2989 switch (e) {3015 switch (e) {
2990 .CANCELED => return error.Canceled,
2991 .INVAL => |err| return errnoBug(err),3016 .INVAL => |err| return errnoBug(err),
2992 .FAULT => |err| return errnoBug(err),3017 .FAULT => |err| return errnoBug(err),
2993 .BADF => return error.NotOpenForReading, // File operation on directory.3018 .BADF => return error.NotOpenForReading, // File operation on directory.
...@@ -3018,10 +3043,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io...@@ -3018,10 +3043,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io
3018 try current_thread.checkCancel();3043 try current_thread.checkCancel();
3019 continue;3044 continue;
3020 },3045 },
3046 .CANCELED => return current_thread.endSyscallCanceled(),
3021 else => |e| {3047 else => |e| {
3022 current_thread.endSyscall();3048 current_thread.endSyscall();
3023 switch (e) {3049 switch (e) {
3024 .CANCELED => return error.Canceled,
3025 .INVAL => |err| return errnoBug(err),3050 .INVAL => |err| return errnoBug(err),
3026 .FAULT => |err| return errnoBug(err),3051 .FAULT => |err| return errnoBug(err),
3027 .SRCH => return error.ProcessNotFound,3052 .SRCH => return error.ProcessNotFound,
...@@ -3104,10 +3129,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o...@@ -3104,10 +3129,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o
3104 try current_thread.checkCancel();3129 try current_thread.checkCancel();
3105 continue;3130 continue;
3106 },3131 },
3132 .CANCELED => return current_thread.endSyscallCanceled(),
3107 else => |e| {3133 else => |e| {
3108 current_thread.endSyscall();3134 current_thread.endSyscall();
3109 switch (e) {3135 switch (e) {
3110 .CANCELED => return error.Canceled,
3111 .INVAL => |err| return errnoBug(err),3136 .INVAL => |err| return errnoBug(err),
3112 .FAULT => |err| return errnoBug(err),3137 .FAULT => |err| return errnoBug(err),
3113 .AGAIN => |err| return errnoBug(err),3138 .AGAIN => |err| return errnoBug(err),
...@@ -3142,10 +3167,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o...@@ -3142,10 +3167,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o
3142 try current_thread.checkCancel();3167 try current_thread.checkCancel();
3143 continue;3168 continue;
3144 },3169 },
3170 .CANCELED => return current_thread.endSyscallCanceled(),
3145 else => |e| {3171 else => |e| {
3146 current_thread.endSyscall();3172 current_thread.endSyscall();
3147 switch (e) {3173 switch (e) {
3148 .CANCELED => return error.Canceled,
3149 .INVAL => |err| return errnoBug(err),3174 .INVAL => |err| return errnoBug(err),
3150 .FAULT => |err| return errnoBug(err),3175 .FAULT => |err| return errnoBug(err),
3151 .SRCH => return error.ProcessNotFound,3176 .SRCH => return error.ProcessNotFound,
...@@ -3244,10 +3269,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr...@@ -3244,10 +3269,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
3244 try current_thread.checkCancel();3269 try current_thread.checkCancel();
3245 continue;3270 continue;
3246 },3271 },
3272 .CANCELED => return current_thread.endSyscallCanceled(),
3247 else => |e| {3273 else => |e| {
3248 current_thread.endSyscall();3274 current_thread.endSyscall();
3249 switch (e) {3275 switch (e) {
3250 .CANCELED => return error.Canceled,
3251 .BADF => |err| return errnoBug(err), // File descriptor used after closed.3276 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3252 .INVAL => return error.Unseekable,3277 .INVAL => return error.Unseekable,
3253 .OVERFLOW => return error.Unseekable,3278 .OVERFLOW => return error.Unseekable,
...@@ -3277,10 +3302,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr...@@ -3277,10 +3302,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
3277 try current_thread.checkCancel();3302 try current_thread.checkCancel();
3278 continue;3303 continue;
3279 },3304 },
3305 .CANCELED => return current_thread.endSyscallCanceled(),
3280 else => |e| {3306 else => |e| {
3281 current_thread.endSyscall();3307 current_thread.endSyscall();
3282 switch (e) {3308 switch (e) {
3283 .CANCELED => return error.Canceled,
3284 .BADF => |err| return errnoBug(err), // File descriptor used after closed.3309 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3285 .INVAL => return error.Unseekable,3310 .INVAL => return error.Unseekable,
3286 .OVERFLOW => return error.Unseekable,3311 .OVERFLOW => return error.Unseekable,
...@@ -3306,10 +3331,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr...@@ -3306,10 +3331,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
3306 try current_thread.checkCancel();3331 try current_thread.checkCancel();
3307 continue;3332 continue;
3308 },3333 },
3334 .CANCELED => return current_thread.endSyscallCanceled(),
3309 else => |e| {3335 else => |e| {
3310 current_thread.endSyscall();3336 current_thread.endSyscall();
3311 switch (e) {3337 switch (e) {
3312 .CANCELED => return error.Canceled,
3313 .BADF => |err| return errnoBug(err), // File descriptor used after closed.3338 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3314 .INVAL => return error.Unseekable,3339 .INVAL => return error.Unseekable,
3315 .OVERFLOW => return error.Unseekable,3340 .OVERFLOW => return error.Unseekable,
...@@ -3430,7 +3455,8 @@ fn nowWasi(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {...@@ -3430,7 +3455,8 @@ fn nowWasi(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {
3430const sleep = switch (native_os) {3455const sleep = switch (native_os) {
3431 .windows => sleepWindows,3456 .windows => sleepWindows,
3432 .wasi => sleepWasi,3457 .wasi => sleepWasi,
3433 .linux => sleepLinux,3458 // Since we use musl's pthread_cancel, it's important that all the syscalls go through libc.
3459 .linux => if (is_musl) sleepPosix else sleepLinux,
3434 else => sleepPosix,3460 else => sleepPosix,
3435};3461};
34363462
...@@ -3462,10 +3488,10 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -3462,10 +3488,10 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
3462 try current_thread.checkCancel();3488 try current_thread.checkCancel();
3463 continue;3489 continue;
3464 },3490 },
3491 .CANCELED => return current_thread.endSyscallCanceled(),
3465 else => |e| {3492 else => |e| {
3466 current_thread.endSyscall();3493 current_thread.endSyscall();
3467 switch (e) {3494 switch (e) {
3468 .CANCELED => return error.Canceled,
3469 .INVAL => return error.UnsupportedClock,3495 .INVAL => return error.UnsupportedClock,
3470 else => |err| return posix.unexpectedErrno(err),3496 else => |err| return posix.unexpectedErrno(err),
3471 }3497 }
...@@ -3540,11 +3566,9 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -3540,11 +3566,9 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
3540 try current_thread.checkCancel();3566 try current_thread.checkCancel();
3541 continue;3567 continue;
3542 },3568 },
3543 else => {3569 .CANCELED => return current_thread.endSyscallCanceled(),
3544 // This prong handles success as well as unexpected errors.3570 // This prong handles success as well as unexpected errors.
3545 current_thread.endSyscall();3571 else => return current_thread.endSyscall(),
3546 return;
3547 },
3548 }3572 }
3549 }3573 }
3550}3574}
...@@ -3616,10 +3640,10 @@ fn netListenIpPosix(...@@ -3616,10 +3640,10 @@ fn netListenIpPosix(
3616 try current_thread.checkCancel();3640 try current_thread.checkCancel();
3617 continue;3641 continue;
3618 },3642 },
3643 .CANCELED => return current_thread.endSyscallCanceled(),
3619 else => |e| {3644 else => |e| {
3620 current_thread.endSyscall();3645 current_thread.endSyscall();
3621 switch (e) {3646 switch (e) {
3622 .CANCELED => return error.Canceled,
3623 .ADDRINUSE => return error.AddressInUse,3647 .ADDRINUSE => return error.AddressInUse,
3624 .BADF => |err| return errnoBug(err), // File descriptor used after closed.3648 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3625 else => |err| return posix.unexpectedErrno(err),3649 else => |err| return posix.unexpectedErrno(err),
...@@ -3777,10 +3801,10 @@ fn netListenUnixPosix(...@@ -3777,10 +3801,10 @@ fn netListenUnixPosix(
3777 try current_thread.checkCancel();3801 try current_thread.checkCancel();
3778 continue;3802 continue;
3779 },3803 },
3804 .CANCELED => return current_thread.endSyscallCanceled(),
3780 else => |e| {3805 else => |e| {
3781 current_thread.endSyscall();3806 current_thread.endSyscall();
3782 switch (e) {3807 switch (e) {
3783 .CANCELED => return error.Canceled,
3784 .ADDRINUSE => return error.AddressInUse,3808 .ADDRINUSE => return error.AddressInUse,
3785 .BADF => |err| return errnoBug(err), // File descriptor used after closed.3809 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3786 else => |err| return posix.unexpectedErrno(err),3810 else => |err| return posix.unexpectedErrno(err),
...@@ -3901,10 +3925,10 @@ fn posixBindUnix(...@@ -3901,10 +3925,10 @@ fn posixBindUnix(
3901 try current_thread.checkCancel();3925 try current_thread.checkCancel();
3902 continue;3926 continue;
3903 },3927 },
3928 .CANCELED => return current_thread.endSyscallCanceled(),
3904 else => |e| {3929 else => |e| {
3905 current_thread.endSyscall();3930 current_thread.endSyscall();
3906 switch (e) {3931 switch (e) {
3907 .CANCELED => return error.Canceled,
3908 .ACCES => return error.AccessDenied,3932 .ACCES => return error.AccessDenied,
3909 .ADDRINUSE => return error.AddressInUse,3933 .ADDRINUSE => return error.AddressInUse,
3910 .AFNOSUPPORT => return error.AddressFamilyUnsupported,3934 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
...@@ -3946,10 +3970,10 @@ fn posixBind(...@@ -3946,10 +3970,10 @@ fn posixBind(
3946 try current_thread.checkCancel();3970 try current_thread.checkCancel();
3947 continue;3971 continue;
3948 },3972 },
3973 .CANCELED => return current_thread.endSyscallCanceled(),
3949 else => |e| {3974 else => |e| {
3950 current_thread.endSyscall();3975 current_thread.endSyscall();
3951 switch (e) {3976 switch (e) {
3952 .CANCELED => return error.Canceled,
3953 .ADDRINUSE => return error.AddressInUse,3977 .ADDRINUSE => return error.AddressInUse,
3954 .BADF => |err| return errnoBug(err), // File descriptor used after closed.3978 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3955 .INVAL => |err| return errnoBug(err), // invalid parameters3979 .INVAL => |err| return errnoBug(err), // invalid parameters
...@@ -3982,10 +4006,10 @@ fn posixConnect(...@@ -3982,10 +4006,10 @@ fn posixConnect(
3982 try current_thread.checkCancel();4006 try current_thread.checkCancel();
3983 continue;4007 continue;
3984 },4008 },
4009 .CANCELED => return current_thread.endSyscallCanceled(),
3985 else => |e| {4010 else => |e| {
3986 current_thread.endSyscall();4011 current_thread.endSyscall();
3987 switch (e) {4012 switch (e) {
3988 .CANCELED => return error.Canceled,
3989 .ADDRNOTAVAIL => return error.AddressUnavailable,4013 .ADDRNOTAVAIL => return error.AddressUnavailable,
3990 .AFNOSUPPORT => return error.AddressFamilyUnsupported,4014 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
3991 .AGAIN, .INPROGRESS => return error.WouldBlock,4015 .AGAIN, .INPROGRESS => return error.WouldBlock,
...@@ -4029,10 +4053,10 @@ fn posixConnectUnix(...@@ -4029,10 +4053,10 @@ fn posixConnectUnix(
4029 try current_thread.checkCancel();4053 try current_thread.checkCancel();
4030 continue;4054 continue;
4031 },4055 },
4056 .CANCELED => return current_thread.endSyscallCanceled(),
4032 else => |e| {4057 else => |e| {
4033 current_thread.endSyscall();4058 current_thread.endSyscall();
4034 switch (e) {4059 switch (e) {
4035 .CANCELED => return error.Canceled,
4036 .AFNOSUPPORT => return error.AddressFamilyUnsupported,4060 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
4037 .AGAIN => return error.WouldBlock,4061 .AGAIN => return error.WouldBlock,
4038 .INPROGRESS => return error.WouldBlock,4062 .INPROGRESS => return error.WouldBlock,
...@@ -4074,10 +4098,10 @@ fn posixGetSockName(...@@ -4074,10 +4098,10 @@ fn posixGetSockName(
4074 try current_thread.checkCancel();4098 try current_thread.checkCancel();
4075 continue;4099 continue;
4076 },4100 },
4101 .CANCELED => return current_thread.endSyscallCanceled(),
4077 else => |e| {4102 else => |e| {
4078 current_thread.endSyscall();4103 current_thread.endSyscall();
4079 switch (e) {4104 switch (e) {
4080 .CANCELED => return error.Canceled,
4081 .BADF => |err| return errnoBug(err), // File descriptor used after closed.4105 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
4082 .FAULT => |err| return errnoBug(err),4106 .FAULT => |err| return errnoBug(err),
4083 .INVAL => |err| return errnoBug(err), // invalid parameters4107 .INVAL => |err| return errnoBug(err), // invalid parameters
...@@ -4142,10 +4166,10 @@ fn setSocketOption(current_thread: *Thread, fd: posix.fd_t, level: i32, opt_name...@@ -4142,10 +4166,10 @@ fn setSocketOption(current_thread: *Thread, fd: posix.fd_t, level: i32, opt_name
4142 try current_thread.checkCancel();4166 try current_thread.checkCancel();
4143 continue;4167 continue;
4144 },4168 },
4169 .CANCELED => return current_thread.endSyscallCanceled(),
4145 else => |e| {4170 else => |e| {
4146 current_thread.endSyscall();4171 current_thread.endSyscall();
4147 switch (e) {4172 switch (e) {
4148 .CANCELED => return error.Canceled,
4149 .BADF => |err| return errnoBug(err), // File descriptor used after closed.4173 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
4150 .NOTSOCK => |err| return errnoBug(err),4174 .NOTSOCK => |err| return errnoBug(err),
4151 .INVAL => |err| return errnoBug(err),4175 .INVAL => |err| return errnoBug(err),
...@@ -4472,12 +4496,10 @@ fn openSocketPosix(...@@ -4472,12 +4496,10 @@ fn openSocketPosix(
4472 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {4496 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
4473 .SUCCESS => break,4497 .SUCCESS => break,
4474 .INTR => continue,4498 .INTR => continue,
4475 else => |e| {4499 .CANCELED => return current_thread.endSyscallCanceled(),
4500 else => |err| {
4476 current_thread.endSyscall();4501 current_thread.endSyscall();
4477 switch (e) {4502 return posix.unexpectedErrno(err);
4478 .CANCELED => return error.Canceled,
4479 else => |err| return posix.unexpectedErrno(err),
4480 }
4481 },4503 },
4482 }4504 }
4483 };4505 };
...@@ -4488,10 +4510,10 @@ fn openSocketPosix(...@@ -4488,10 +4510,10 @@ fn openSocketPosix(
4488 try current_thread.checkCancel();4510 try current_thread.checkCancel();
4489 continue;4511 continue;
4490 },4512 },
4513 .CANCELED => return current_thread.endSyscallCanceled(),
4491 else => |e| {4514 else => |e| {
4492 current_thread.endSyscall();4515 current_thread.endSyscall();
4493 switch (e) {4516 switch (e) {
4494 .CANCELED => return error.Canceled,
4495 .AFNOSUPPORT => return error.AddressFamilyUnsupported,4517 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
4496 .INVAL => return error.ProtocolUnsupportedBySystem,4518 .INVAL => return error.ProtocolUnsupportedBySystem,
4497 .MFILE => return error.ProcessFdQuotaExceeded,4519 .MFILE => return error.ProcessFdQuotaExceeded,
...@@ -4590,10 +4612,10 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve...@@ -4590,10 +4612,10 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
4590 try current_thread.checkCancel();4612 try current_thread.checkCancel();
4591 continue;4613 continue;
4592 },4614 },
4615 .CANCELED => return current_thread.endSyscallCanceled(),
4593 else => |e| {4616 else => |e| {
4594 current_thread.endSyscall();4617 current_thread.endSyscall();
4595 switch (e) {4618 switch (e) {
4596 .CANCELED => return error.Canceled,
4597 .AGAIN => |err| return errnoBug(err),4619 .AGAIN => |err| return errnoBug(err),
4598 .BADF => |err| return errnoBug(err), // File descriptor used after closed.4620 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
4599 .CONNABORTED => return error.ConnectionAborted,4621 .CONNABORTED => return error.ConnectionAborted,
...@@ -4699,10 +4721,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -4699,10 +4721,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
4699 try current_thread.checkCancel();4721 try current_thread.checkCancel();
4700 continue;4722 continue;
4701 },4723 },
4724 .CANCELED => return current_thread.endSyscallCanceled(),
4702 else => |e| {4725 else => |e| {
4703 current_thread.endSyscall();4726 current_thread.endSyscall();
4704 switch (e) {4727 switch (e) {
4705 .CANCELED => return error.Canceled,
4706 .INVAL => |err| return errnoBug(err),4728 .INVAL => |err| return errnoBug(err),
4707 .FAULT => |err| return errnoBug(err),4729 .FAULT => |err| return errnoBug(err),
4708 .AGAIN => |err| return errnoBug(err),4730 .AGAIN => |err| return errnoBug(err),
...@@ -4732,10 +4754,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -4732,10 +4754,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
4732 try current_thread.checkCancel();4754 try current_thread.checkCancel();
4733 continue;4755 continue;
4734 },4756 },
4757 .CANCELED => return current_thread.endSyscallCanceled(),
4735 else => |e| {4758 else => |e| {
4736 current_thread.endSyscall();4759 current_thread.endSyscall();
4737 switch (e) {4760 switch (e) {
4738 .CANCELED => return error.Canceled,
4739 .INVAL => |err| return errnoBug(err),4761 .INVAL => |err| return errnoBug(err),
4740 .FAULT => |err| return errnoBug(err),4762 .FAULT => |err| return errnoBug(err),
4741 .AGAIN => |err| return errnoBug(err),4763 .AGAIN => |err| return errnoBug(err),
...@@ -4968,10 +4990,10 @@ fn netSendOne(...@@ -4968,10 +4990,10 @@ fn netSendOne(
4968 try current_thread.checkCancel();4990 try current_thread.checkCancel();
4969 continue;4991 continue;
4970 },4992 },
4993 .CANCELED => return current_thread.endSyscallCanceled(),
4971 else => |e| {4994 else => |e| {
4972 current_thread.endSyscall();4995 current_thread.endSyscall();
4973 switch (e) {4996 switch (e) {
4974 .CANCELED => return error.Canceled,
4975 .ACCES => return error.AccessDenied,4997 .ACCES => return error.AccessDenied,
4976 .ALREADY => return error.FastOpenAlreadyInProgress,4998 .ALREADY => return error.FastOpenAlreadyInProgress,
4977 .BADF => |err| return errnoBug(err), // File descriptor used after closed.4999 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -5045,10 +5067,10 @@ fn netSendMany(...@@ -5045,10 +5067,10 @@ fn netSendMany(
5045 try current_thread.checkCancel();5067 try current_thread.checkCancel();
5046 continue;5068 continue;
5047 },5069 },
5070 .CANCELED => return current_thread.endSyscallCanceled(),
5048 else => |e| {5071 else => |e| {
5049 current_thread.endSyscall();5072 current_thread.endSyscall();
5050 switch (e) {5073 switch (e) {
5051 .CANCELED => return error.Canceled,
5052 .AGAIN => |err| return errnoBug(err),5074 .AGAIN => |err| return errnoBug(err),
5053 .ALREADY => return error.FastOpenAlreadyInProgress,5075 .ALREADY => return error.FastOpenAlreadyInProgress,
5054 .BADF => |err| return errnoBug(err), // File descriptor used after closed.5076 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -5178,7 +5200,7 @@ fn netReceivePosix(...@@ -5178,7 +5200,7 @@ fn netReceivePosix(
5178 continue :recv;5200 continue :recv;
5179 },5201 },
5180 .INTR => continue,5202 .INTR => continue,
5181 .CANCELED => return .{ error.Canceled, message_i },5203 .CANCELED => return .{ current_thread.endSyscallCanceled(), message_i },
51825204
5183 .FAULT => |err| return .{ errnoBug(err), message_i },5205 .FAULT => |err| return .{ errnoBug(err), message_i },
5184 .INVAL => |err| return .{ errnoBug(err), message_i },5206 .INVAL => |err| return .{ errnoBug(err), message_i },
...@@ -5187,7 +5209,7 @@ fn netReceivePosix(...@@ -5187,7 +5209,7 @@ fn netReceivePosix(
5187 }5209 }
5188 },5210 },
5189 .INTR => continue,5211 .INTR => continue,
5190 .CANCELED => return .{ error.Canceled, message_i },5212 .CANCELED => return .{ current_thread.endSyscallCanceled(), message_i },
51915213
5192 .BADF => |err| return .{ errnoBug(err), message_i },5214 .BADF => |err| return .{ errnoBug(err), message_i },
5193 .NFILE => return .{ error.SystemFdQuotaExceeded, message_i },5215 .NFILE => return .{ error.SystemFdQuotaExceeded, message_i },
...@@ -5306,10 +5328,10 @@ fn netWritePosix(...@@ -5306,10 +5328,10 @@ fn netWritePosix(
5306 try current_thread.checkCancel();5328 try current_thread.checkCancel();
5307 continue;5329 continue;
5308 },5330 },
5331 .CANCELED => return current_thread.endSyscallCanceled(),
5309 else => |e| {5332 else => |e| {
5310 current_thread.endSyscall();5333 current_thread.endSyscall();
5311 switch (e) {5334 switch (e) {
5312 .CANCELED => return error.Canceled,
5313 .ACCES => |err| return errnoBug(err),5335 .ACCES => |err| return errnoBug(err),
5314 .AGAIN => |err| return errnoBug(err),5336 .AGAIN => |err| return errnoBug(err),
5315 .ALREADY => return error.FastOpenAlreadyInProgress,5337 .ALREADY => return error.FastOpenAlreadyInProgress,
...@@ -5405,7 +5427,7 @@ fn netWriteWindows(...@@ -5405,7 +5427,7 @@ fn netWriteWindows(
5405 };5427 };
5406 switch (wsa_error) {5428 switch (wsa_error) {
5407 .EINTR => continue,5429 .EINTR => continue,
5408 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,5430 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return current_thread.endSyscallCanceled(),
5409 .NOTINITIALISED => {5431 .NOTINITIALISED => {
5410 try initializeWsa(t);5432 try initializeWsa(t);
5411 continue;5433 continue;
...@@ -5517,10 +5539,10 @@ fn netInterfaceNameResolve(...@@ -5517,10 +5539,10 @@ fn netInterfaceNameResolve(
5517 try current_thread.checkCancel();5539 try current_thread.checkCancel();
5518 continue;5540 continue;
5519 },5541 },
5542 .CANCELED => return current_thread.endSyscallCanceled(),
5520 else => |e| {5543 else => |e| {
5521 current_thread.endSyscall();5544 current_thread.endSyscall();
5522 switch (e) {5545 switch (e) {
5523 .CANCELED => return error.Canceled,
5524 .INVAL => |err| return errnoBug(err), // Bad parameters.5546 .INVAL => |err| return errnoBug(err), // Bad parameters.
5525 .NOTTY => |err| return errnoBug(err),5547 .NOTTY => |err| return errnoBug(err),
5526 .NXIO => |err| return errnoBug(err),5548 .NXIO => |err| return errnoBug(err),
...@@ -5818,12 +5840,10 @@ fn netLookupFallible(...@@ -5818,12 +5840,10 @@ fn netLookupFallible(
5818 try current_thread.checkCancel();5840 try current_thread.checkCancel();
5819 continue;5841 continue;
5820 },5842 },
5843 .CANCELED => return current_thread.endSyscallCanceled(),
5821 else => |e| {5844 else => |e| {
5822 current_thread.endSyscall();5845 current_thread.endSyscall();
5823 switch (e) {5846 return posix.unexpectedErrno(e);
5824 .CANCELED => return error.Canceled,
5825 else => |inner| return posix.unexpectedErrno(inner),
5826 }
5827 },5847 },
5828 },5848 },
5829 else => |e| {5849 else => |e| {
lib/std/c.zig+17
...@@ -10881,6 +10881,23 @@ pub extern "c" fn pthread_create(...@@ -10881,6 +10881,23 @@ pub extern "c" fn pthread_create(
10881 start_routine: *const fn (?*anyopaque) callconv(.c) ?*anyopaque,10881 start_routine: *const fn (?*anyopaque) callconv(.c) ?*anyopaque,
10882 noalias arg: ?*anyopaque,10882 noalias arg: ?*anyopaque,
10883) E;10883) E;
10884pub const pthread_cancelstate = switch (native_os) {
10885 .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => enum(c_int) {
10886 ENABLE = 1,
10887 DISABLE = 0,
10888 },
10889 .linux => if (native_abi.isMusl()) enum(c_int) {
10890 ENABLE = 0,
10891 DISABLE = 1,
10892 MASKED = 2,
10893 } else if (native_abi.isGnu()) enum(c_int) {
10894 ENABLE = 0,
10895 DISABLE = 1,
10896 },
10897 else => void,
10898};
10899pub extern "c" fn pthread_setcancelstate(pthread_cancelstate, ?*pthread_cancelstate) E;
10900pub extern "c" fn pthread_cancel(pthread_t) E;
10884pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) E;10901pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) E;
10885pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *anyopaque, stacksize: usize) E;10902pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *anyopaque, stacksize: usize) E;
10886pub extern "c" fn pthread_attr_setstacksize(attr: *pthread_attr_t, stacksize: usize) E;10903pub extern "c" fn pthread_attr_setstacksize(attr: *pthread_attr_t, stacksize: usize) E;
lib/std/posix.zig+1
...@@ -1360,6 +1360,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {...@@ -1360,6 +1360,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {
1360 .PIPE => return error.BrokenPipe,1360 .PIPE => return error.BrokenPipe,
1361 .CONNRESET => return error.ConnectionResetByPeer,1361 .CONNRESET => return error.ConnectionResetByPeer,
1362 .BUSY => return error.DeviceBusy,1362 .BUSY => return error.DeviceBusy,
1363 .CANCELED => return error.Canceled,
1363 else => |err| return unexpectedErrno(err),1364 else => |err| return unexpectedErrno(err),
1364 }1365 }
1365 }1366 }