diff options
| author | LemonBoy <thatlemon@gmail.com> | 2019-05-04 09:03:01 +0200 |
|---|---|---|
| committer | LemonBoy <thatlemon@gmail.com> | 2019-05-04 09:03:01 +0200 |
| commit | 98bc2b73bf6974a782e2df0ea71b409a68e030fd (patch) | |
| tree | 4eb2371bee9c6efcf6e90a48d629fb9bc207af2f /std/os/time.zig | |
| parent | b612512bb500defd399a11dfa47c83cefe4d87b5 (diff) | |
| download | zig-98bc2b73bf6974a782e2df0ea71b409a68e030fd.tar.gz zig-98bc2b73bf6974a782e2df0ea71b409a68e030fd.zip | |
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 (limited to 'std/os/time.zig')
| -rw-r--r-- | std/os/time.zig | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/std/os/time.zig b/std/os/time.zig index fb39fda1de..99c8b59927 100644 --- 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, |
