commit ecb9ddf2672fa1f067c240d914a5baf3a4d2d8a4 (tree)
parent 9b415761dd66904aef363e387b4501f3ddd0bf76
Author: Brandon Black <bblack@wikimedia.org>
Date: Wed, 28 Jan 2026 16:54:04 -0600
Threaded.sleepPosix: fix libc error handling
Confusingly, the POSIX spec for clock_nanosleep() says it returns
*positive* error values directly and does not touch `errno`. Not
detecting EINTR properly here was breaking the cancellation of
threads blocked in this call when linking libc.
Diffstat:
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
@@ -10083,10 +10083,12 @@ fn sleepPosix(timeout: Io.Timeout) Io.SleepError!void {
var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);
const syscall: Syscall = try .start();
while (true) {
- switch (posix.errno(posix.system.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
+ const rc = posix.system.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
.none, .duration => false,
.deadline => true,
- } }, ×pec, ×pec))) {
+ } }, ×pec, ×pec);
+ // POSIX-standard libc clock_nanosleep() returns *positive* errno values directly
+ switch (if (builtin.link_libc) @as(posix.E, @enumFromInt(rc)) else posix.errno(rc)) {
.SUCCESS => {
syscall.finish();
return;