commit 198b6bc554ae29cc49c21d7904fd130716e60f14
parent bbe9e6bb6f1cc4fc91cd096fda424ee42d33ca9d
Author: Sebastian <sebastian@sebsite.pw>
Date: Sat, 9 Dec 2023 21:31:54 -0500
time: change signature of *_to_timespec funcs
Also fixes a memory management "bug" in sleep. The variable req was set
to the address of a variable local to the loop, which works as of now
but which I assume is undefined behavior (the spec is currently silent
about this so it's tough to say).
This is a breaking change: existing code can be migrated by taking the
value of the function result, rather than creating a binding and passing
it in as a pointer.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
7 files changed, 36 insertions(+), 50 deletions(-)
diff --git a/linux/timerfd/+linux/timerfd.ha b/linux/timerfd/+linux/timerfd.ha
@@ -63,27 +63,22 @@ export fn set(
exp: expiration,
flags: set_flag,
) (void | errors::error) = {
- let interval_timespec = rt::timespec { ... };
const timerspec = match (exp) {
case let o: oneshot =>
- time::duration_to_timespec(o, &interval_timespec);
yield rt::itimerspec {
it_interval = rt::timespec { tv_sec = 0, tv_nsec = 0 },
- it_value = interval_timespec,
+ it_value = time::duration_to_timespec(o),
};
case let i: interval =>
- time::duration_to_timespec(i, &interval_timespec);
+ const interval_timespec = time::duration_to_timespec(i);
yield rt::itimerspec {
it_interval = interval_timespec,
it_value = interval_timespec,
};
case let id: interval_delayed =>
- let delay_timespec = rt::timespec { ... };
- time::duration_to_timespec(id.0, &interval_timespec);
- time::duration_to_timespec(id.1, &delay_timespec);
yield rt::itimerspec {
- it_interval = interval_timespec,
- it_value = delay_timespec,
+ it_interval = time::duration_to_timespec(id.0),
+ it_value = time::duration_to_timespec(id.1),
};
};
diff --git a/time/+freebsd/functions.ha b/time/+freebsd/functions.ha
@@ -5,16 +5,16 @@ use rt;
// Converts a [[duration]] to an [[rt::timespec]]. This function is
// non-portable.
-export fn duration_to_timespec(n: duration, ts: *rt::timespec) void = {
- ts.tv_sec = n / SECOND;
- ts.tv_nsec = n % SECOND;
+export fn duration_to_timespec(n: duration) rt::timespec = rt::timespec {
+ tv_sec = n / SECOND,
+ tv_nsec = n % SECOND,
};
// Converts an [[instant]] to an [[rt::timespec]]. This function is
// non-portable.
-export fn instant_to_timespec(t: instant, ts: *rt::timespec) void = {
- ts.tv_sec = t.sec;
- ts.tv_nsec = t.nsec;
+export fn instant_to_timespec(t: instant) rt::timespec = rt::timespec {
+ tv_sec = t.sec,
+ tv_nsec = t.nsec,
};
// Converts a [[rt::timespec]] to an [[instant]]. This function is
@@ -25,20 +25,18 @@ export fn timespec_to_instant(ts: rt::timespec) instant = instant {
};
// Yields the process to the kernel and returns after the requested duration.
-export fn sleep(n: duration) void = {
- let in = rt::timespec { ... };
- duration_to_timespec(n, &in);
- let req = ∈
+export fn sleep(d: duration) void = {
+ let req = duration_to_timespec(d);
for (true) {
let res = rt::timespec { ... };
- match (rt::nanosleep(req, &res)) {
+ match (rt::nanosleep(&req, &res)) {
case void =>
return;
case let err: rt::errno =>
switch (err) {
case rt::EINTR =>
- req = &res;
+ req = res;
case =>
abort("Unexpected error from nanosleep");
};
diff --git a/time/+linux/functions.ha b/time/+linux/functions.ha
@@ -6,16 +6,16 @@ use rt;
// Converts a [[duration]] to an [[rt::timespec]]. This function is
// non-portable.
-export fn duration_to_timespec(d: duration, ts: *rt::timespec) void = {
- ts.tv_sec = d / SECOND;
- ts.tv_nsec = d % SECOND;
+export fn duration_to_timespec(d: duration) rt::timespec = rt::timespec {
+ tv_sec = d / SECOND,
+ tv_nsec = d % SECOND,
};
// Converts an [[instant]] to an [[rt::timespec]]. This function is
// non-portable.
-export fn instant_to_timespec(t: instant, ts: *rt::timespec) void = {
- ts.tv_sec = t.sec;
- ts.tv_nsec = t.nsec;
+export fn instant_to_timespec(t: instant) rt::timespec = rt::timespec {
+ tv_sec = t.sec,
+ tv_nsec = t.nsec,
};
// Converts a [[rt::timespec]] to an [[instant]]. This function is non-portable.
@@ -26,19 +26,17 @@ export fn timespec_to_instant(ts: rt::timespec) instant = instant {
// Yields the process to the kernel and returns after the requested duration.
export fn sleep(d: duration) void = {
- let in = rt::timespec { ... };
- duration_to_timespec(d, &in);
- let req = ∈
+ let req = duration_to_timespec(d);
for (true) {
let res = rt::timespec { ... };
- match (rt::nanosleep(req, &res)) {
+ match (rt::nanosleep(&req, &res)) {
case void =>
return;
case let err: rt::errno =>
switch (err) {
case rt::EINTR =>
- req = &res;
+ req = res;
case =>
abort("Unexpected error from nanosleep");
};
diff --git a/time/+openbsd/functions.ha b/time/+openbsd/functions.ha
@@ -5,16 +5,16 @@ use rt;
// Converts a [[duration]] to an [[rt::timespec]]. This function is
// non-portable.
-export fn duration_to_timespec(n: duration, ts: *rt::timespec) void = {
- ts.tv_sec = n / SECOND;
- ts.tv_nsec = n % SECOND;
+export fn duration_to_timespec(n: duration) rt::timespec = rt::timespec {
+ tv_sec = n / SECOND,
+ tv_nsec = n % SECOND,
};
// Converts an [[instant]] to an [[rt::timespec]]. This function is
// non-portable.
-export fn instant_to_timespec(t: instant, ts: *rt::timespec) void = {
- ts.tv_sec = t.sec;
- ts.tv_nsec = t.nsec;
+export fn instant_to_timespec(t: instant) rt::timespec = rt::timespec {
+ tv_sec = t.sec,
+ tv_nsec = t.nsec,
};
// Converts a [[rt::timespec]] to an [[instant]]. This function is
@@ -25,20 +25,18 @@ export fn timespec_to_instant(ts: rt::timespec) instant = instant {
};
// Yields the process to the kernel and returns after the requested duration.
-export fn sleep(n: duration) void = {
- let in = rt::timespec { ... };
- duration_to_timespec(n, &in);
- let req = ∈
+export fn sleep(d: duration) void = {
+ let req = duration_to_timespec(d);
for (true) {
let res = rt::timespec { ... };
- match (rt::nanosleep(req, &res)) {
+ match (rt::nanosleep(&req, &res)) {
case void =>
return;
case let err: rt::errno =>
switch (err) {
case rt::EINTR =>
- req = &res;
+ req = res;
case =>
abort("Unexpected error from nanosleep");
};
diff --git a/unix/poll/+freebsd.ha b/unix/poll/+freebsd.ha
@@ -39,8 +39,7 @@ export fn poll(
fds: []pollfd,
timeout: time::duration,
) (uint | error) = {
- let ts = rt::timespec { ... };
- time::duration_to_timespec(timeout, &ts);
+ let ts = time::duration_to_timespec(timeout);
let ts = if (timeout == INDEF) null else &ts;
match (rt::ppoll(fds: *[*]pollfd: *[*]rt::pollfd, len(fds): rt::nfds_t, ts, null)) {
case let err: rt::errno =>
diff --git a/unix/poll/+linux.ha b/unix/poll/+linux.ha
@@ -39,8 +39,7 @@ export fn poll(
fds: []pollfd,
timeout: time::duration,
) (uint | error) = {
- let ts = rt::timespec { ... };
- time::duration_to_timespec(timeout, &ts);
+ let ts = time::duration_to_timespec(timeout);
let ts = if (timeout == INDEF) null else &ts;
match (rt::ppoll(fds: *[*]pollfd: *[*]rt::pollfd, len(fds), ts, null)) {
case let err: rt::errno =>
diff --git a/unix/poll/+openbsd.ha b/unix/poll/+openbsd.ha
@@ -39,8 +39,7 @@ export fn poll(
fds: []pollfd,
timeout: time::duration,
) (uint | error) = {
- let ts = rt::timespec { ... };
- time::duration_to_timespec(timeout, &ts);
+ let ts = time::duration_to_timespec(timeout);
let ts = if (timeout == INDEF) null else &ts;
match (rt::ppoll(fds: *[*]pollfd: *[*]rt::pollfd, len(fds): rt::nfds_t, ts, null)) {
case let err: rt::errno =>