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");...@@ -3,6 +3,7 @@ const builtin = @import("builtin");
3const Os = builtin.Os;3const Os = builtin.Os;
4const debug = std.debug;4const debug = std.debug;
5const testing = std.testing;5const testing = std.testing;
6const math = std.math;
67
7const windows = std.os.windows;8const windows = std.os.windows;
8const linux = std.os.linux;9const linux = std.os.linux;
...@@ -30,16 +31,26 @@ pub fn sleep(nanoseconds: u64) void {...@@ -30,16 +31,26 @@ pub fn sleep(nanoseconds: u64) void {
30}31}
3132
32pub fn posixSleep(seconds: u63, nanoseconds: u63) void {33pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
33 var req = posix.timespec{34 var req: posix.timespec = undefined;
34 .tv_sec = @intCast(isize, seconds),
35 .tv_nsec = @intCast(isize, nanoseconds),
36 };
37 var rem: posix.timespec = undefined;35 var rem: posix.timespec = undefined;
36
37 var req_sec = seconds;
38 var req_nsec = nanoseconds;
39
38 while (true) {40 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
39 const ret_val = posix.nanosleep(&req, &rem);47 const ret_val = posix.nanosleep(&req, &rem);
40 const err = posix.getErrno(ret_val);48 const err = posix.getErrno(ret_val);
41 if (err == 0) return;
42 switch (err) {49 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 },
43 posix.EFAULT => unreachable,54 posix.EFAULT => unreachable,
44 posix.EINVAL => {55 posix.EINVAL => {
45 // Sometimes Darwin returns EINVAL for no reason.56 // Sometimes Darwin returns EINVAL for no reason.
...@@ -47,7 +58,8 @@ pub fn posixSleep(seconds: u63, nanoseconds: u63) void {...@@ -47,7 +58,8 @@ pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
47 return;58 return;
48 },59 },
49 posix.EINTR => {60 posix.EINTR => {
50 req = rem;61 req_sec += @intCast(u63, rem.tv_sec);
62 req_nsec = @intCast(u63, rem.tv_nsec);
51 continue;63 continue;
52 },64 },
53 else => return,65 else => return,