commit fcdde3e4c796fcaf160b6161040df8d458523e95 (tree)
parent fce7878a9149caa80433e6d650e0bd7f60d345fd
Author: Matthew Lugg <mlugg@mlugg.co.uk>
Date: Wed, 4 Feb 2026 15:36:25 +0100
std.Io.Threaded: gracefully handle race leading to ESRCH in unpark()
Diffstat:
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
@@ -17548,8 +17548,8 @@ fn unpark(tids: []const UnparkTid, addr_hint: ?*const anyopaque) void {
switch (posix.errno(std.c._lwp_unpark_all(@ptrCast(tids.ptr), tids.len, addr_hint))) {
.SUCCESS => return,
// For errors, fall through to a loop over `tids`, though this is only expected to
- // be possible for ENOMEM (and even that is questionable).
- .SRCH => recoverableOsBugDetected(),
+ // be possible for ENOMEM (even that is questionable) and ESRCH (see comment below).
+ .SRCH => {},
.FAULT => recoverableOsBugDetected(),
.INVAL => recoverableOsBugDetected(),
.NOMEM => {},
@@ -17558,7 +17558,11 @@ fn unpark(tids: []const UnparkTid, addr_hint: ?*const anyopaque) void {
for (tids) |tid| {
switch (posix.errno(std.c._lwp_unpark(@bitCast(tid), addr_hint))) {
.SUCCESS => {},
- .SRCH => recoverableOsBugDetected(),
+ .SRCH => {
+ // This can happen in a rare race: the thread might have been spuriously
+ // unparked, so already observed the changing status, and from there have
+ // exited. That's okay, because the thread has woken up like we wanted.
+ },
else => recoverableOsBugDetected(),
}
}