aboutsummaryrefslogtreecommitdiff
path: root/std/os/time.zig
diff options
context:
space:
mode:
authorLemonBoy <thatlemon@gmail.com>2019-05-04 09:03:01 +0200
committerLemonBoy <thatlemon@gmail.com>2019-05-04 09:03:01 +0200
commit98bc2b73bf6974a782e2df0ea71b409a68e030fd (patch)
tree4eb2371bee9c6efcf6e90a48d629fb9bc207af2f /std/os/time.zig
parentb612512bb500defd399a11dfa47c83cefe4d87b5 (diff)
downloadzig-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.zig24
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,