authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-05-04 09:03:01+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-05-04 09:03:01+02:00
log98bc2b73bf6974a782e2df0ea71b409a68e030fd
tree4eb2371bee9c6efcf6e90a48d629fb9bc207af2f
parentb612512bb500defd399a11dfa47c83cefe4d87b5

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.

1 files changed, 18 insertions(+), 6 deletions(-)

std/os/time.zig+18-6
......@@ -3,6 +3,7 @@ const builtin = @import("builtin");
33const Os = builtin.Os;
44const debug = std.debug;
55const testing = std.testing;
6const math = std.math;
67
78const windows = std.os.windows;
89const linux = std.os.linux;
......@@ -30,16 +31,26 @@ pub fn sleep(nanoseconds: u64) void {
3031}
3132
3233pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
33 var req = posix.timespec{
34 .tv_sec = @intCast(isize, seconds),
35 .tv_nsec = @intCast(isize, nanoseconds),
36 };
34 var req: posix.timespec = undefined;
3735 var rem: posix.timespec = undefined;
36
37 var req_sec = seconds;
38 var req_nsec = nanoseconds;
39
3840 while (true) {
41 req.tv_sec = math.min(math.maxInt(isize), req_sec);
42 req.tv_nsec = @intCast(isize, req_nsec);
43
44 req_sec -= @intCast(u63, req.tv_sec);
45 req_nsec = 0;
46
3947 const ret_val = posix.nanosleep(&req, &rem);
4048 const err = posix.getErrno(ret_val);
41 if (err == 0) return;
4249 switch (err) {
50 0 => {
51 // If there's still time to wait keep running the loop
52 if (req_sec == 0 and req_nsec == 0) return;
53 },
4354 posix.EFAULT => unreachable,
4455 posix.EINVAL => {
4556 // Sometimes Darwin returns EINVAL for no reason.
......@@ -47,7 +58,8 @@ pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
4758 return;
4859 },
4960 posix.EINTR => {
50 req = rem;
61 req_sec += @intCast(u63, rem.tv_sec);
62 req_nsec = @intCast(u63, rem.tv_nsec);
5163 continue;
5264 },
5365 else => return,