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