zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 98bc2b73bf6974a782e2df0ea71b409a68e030fd (tree)
parent b612512bb500defd399a11dfa47c83cefe4d87b5
Author: LemonBoy <thatlemon@gmail.com>
Date:   Sat,  4 May 2019 09:03:01 +0200

Implement failsafe logic for posixSleep

Now we'll sleep for the specified amount of time even though the number
of seconds doesn't fit in a `isize` field.

Diffstat:
Mstd/os/time.zig | 24++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/std/os/time.zig b/std/os/time.zig @@ -3,6 +3,7 @@ const builtin = @import("builtin"); const Os = builtin.Os; const debug = std.debug; const testing = std.testing; +const math = std.math; const windows = std.os.windows; const linux = std.os.linux; @@ -30,16 +31,26 @@ pub fn sleep(nanoseconds: u64) void { } pub fn posixSleep(seconds: u63, nanoseconds: u63) void { - var req = posix.timespec{ - .tv_sec = @intCast(isize, seconds), - .tv_nsec = @intCast(isize, nanoseconds), - }; + var req: posix.timespec = undefined; var rem: posix.timespec = undefined; + + var req_sec = seconds; + var req_nsec = nanoseconds; + while (true) { + req.tv_sec = math.min(math.maxInt(isize), req_sec); + req.tv_nsec = @intCast(isize, req_nsec); + + req_sec -= @intCast(u63, req.tv_sec); + req_nsec = 0; + const ret_val = posix.nanosleep(&req, &rem); const err = posix.getErrno(ret_val); - if (err == 0) return; switch (err) { + 0 => { + // If there's still time to wait keep running the loop + if (req_sec == 0 and req_nsec == 0) return; + }, posix.EFAULT => unreachable, posix.EINVAL => { // Sometimes Darwin returns EINVAL for no reason. @@ -47,7 +58,8 @@ pub fn posixSleep(seconds: u63, nanoseconds: u63) void { return; }, posix.EINTR => { - req = rem; + req_sec += @intCast(u63, rem.tv_sec); + req_nsec = @intCast(u63, rem.tv_nsec); continue; }, else => return,