authorgravatar for bblack@wikimedia.orgBrandon Black <bblack@wikimedia.org> 2026-01-28 16:54:04-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-30 06:19:31+01:00
logecb9ddf2672fa1f067c240d914a5baf3a4d2d8a4
treeb819f184ff9070176c232acd5afce33d473b0678
parent9b415761dd66904aef363e387b4501f3ddd0bf76

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.

1 files changed, 4 insertions(+), 2 deletions(-)

lib/std/Io/Threaded.zig+4-2
...@@ -10083,10 +10083,12 @@ fn sleepPosix(timeout: Io.Timeout) Io.SleepError!void {...@@ -10083,10 +10083,12 @@ fn sleepPosix(timeout: Io.Timeout) Io.SleepError!void {
10083 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);10083 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);
10084 const syscall: Syscall = try .start();10084 const syscall: Syscall = try .start();
10085 while (true) {10085 while (true) {
10086 switch (posix.errno(posix.system.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {10086 const rc = posix.system.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
10087 .none, .duration => false,10087 .none, .duration => false,
10088 .deadline => true,10088 .deadline => true,
10089 } }, &timespec, &timespec))) {10089 } }, &timespec, &timespec);
10090 // POSIX-standard libc clock_nanosleep() returns *positive* errno values directly
10091 switch (if (builtin.link_libc) @as(posix.E, @enumFromInt(rc)) else posix.errno(rc)) {
10090 .SUCCESS => {10092 .SUCCESS => {
10091 syscall.finish();10093 syscall.finish();
10092 return;10094 return;