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