time: use `Duration(C.INT64_MAX)` as infinite (#10539)
parent
dd6591b2f5
commit
72358833e0
|
@ -14,7 +14,7 @@ pub const no_timeout = time.Duration(0)
|
|||
|
||||
// infinite_timeout should be given to functions when an infinite_timeout is wanted (i.e. functions
|
||||
// only ever return with data)
|
||||
pub const infinite_timeout = time.Duration(-1)
|
||||
pub const infinite_timeout = time.infinite
|
||||
|
||||
// Shutdown shutsdown a socket and closes it
|
||||
fn shutdown(handle int) ? {
|
||||
|
@ -34,7 +34,7 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool {
|
|||
C.FD_ZERO(&set)
|
||||
C.FD_SET(handle, &set)
|
||||
|
||||
seconds := timeout.milliseconds() / 1000
|
||||
seconds := timeout / time.second
|
||||
microseconds := time.Duration(timeout - (seconds * time.second)).microseconds()
|
||||
|
||||
mut tt := C.timeval{
|
||||
|
@ -93,9 +93,8 @@ fn select_with_retry(handle int, test Select, timeout time.Duration) ?bool {
|
|||
// wait_for_common wraps the common wait code
|
||||
fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ? {
|
||||
if deadline.unix == 0 {
|
||||
// only accept infinite_timeout as a valid
|
||||
// negative timeout - it is handled in @select however
|
||||
if timeout < 0 && timeout != net.infinite_timeout {
|
||||
// do not accept negative timeout
|
||||
if timeout < 0 {
|
||||
return err_timed_out
|
||||
}
|
||||
ready := select_with_retry(handle, test, timeout) ?
|
||||
|
|
|
@ -29,8 +29,8 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool {
|
|||
C.FD_ZERO(&set)
|
||||
C.FD_SET(handle, &set)
|
||||
|
||||
seconds := timeout.milliseconds() / 1000
|
||||
microseconds := timeout - (seconds * time.second)
|
||||
seconds := timeout / time.second
|
||||
microseconds := time.Duration(timeout - (seconds * time.second)).microseconds()
|
||||
|
||||
mut tt := C.timeval{
|
||||
tv_sec: u64(seconds)
|
||||
|
@ -63,9 +63,8 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool {
|
|||
// wait_for_common wraps the common wait code
|
||||
fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ? {
|
||||
if deadline.unix == 0 {
|
||||
// only accept infinite_timeout as a valid
|
||||
// negative timeout - it is handled in @select however
|
||||
if timeout < 0 && timeout != unix.infinite_timeout {
|
||||
// do not accept negative timeout
|
||||
if timeout < 0 {
|
||||
return net.err_timed_out
|
||||
}
|
||||
ready := @select(handle, test, timeout) ?
|
||||
|
@ -117,7 +116,7 @@ const (
|
|||
// infinite_timeout should be given to functions when an infinite_timeout is wanted (i.e. functions
|
||||
// only ever return with data)
|
||||
const (
|
||||
infinite_timeout = time.Duration(-1)
|
||||
infinite_timeout = time.infinite
|
||||
)
|
||||
|
||||
[inline]
|
||||
|
|
|
@ -107,10 +107,7 @@ fn (mut en EpollNotifier) wait(timeout time.Duration) []FdEvent {
|
|||
// the added bonus of making EpollNotifier thread safe
|
||||
events := [512]C.epoll_event{}
|
||||
// populate events with the new events
|
||||
to := match timeout {
|
||||
time.infinite { -1 }
|
||||
else { int(timeout / time.millisecond) }
|
||||
}
|
||||
to := timeout.sys_milliseconds()
|
||||
count := C.epoll_wait(en.epoll_fd, &events[0], events.len, to)
|
||||
|
||||
if count > 0 {
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
module sync
|
||||
|
||||
import time
|
||||
|
||||
fn do_rec_i64(mut ch Channel) {
|
||||
mut sum := i64(0)
|
||||
for _ in 0 .. 300 {
|
||||
|
@ -56,7 +58,7 @@ fn test_select() {
|
|||
mut sl := i64(0)
|
||||
mut objs := [voidptr(&ri), &sl, &rl, &rb]
|
||||
for _ in 0 .. 1200 {
|
||||
idx := channel_select(mut channels, directions, mut objs, -1)
|
||||
idx := channel_select(mut channels, directions, mut objs, time.infinite)
|
||||
match idx {
|
||||
0 {
|
||||
sum += ri
|
||||
|
|
|
@ -602,8 +602,8 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
|||
}
|
||||
|
||||
// Wait `timeout` on any of `channels[i]` until one of them can push (`is_push[i] = true`) or pop (`is_push[i] = false`)
|
||||
// object referenced by `objrefs[i]`. `timeout < 0` means wait unlimited time. `timeout == 0` means return immediately
|
||||
// if no transaction can be performed without waiting.
|
||||
// object referenced by `objrefs[i]`. `timeout = time.infinite` means wait unlimited time. `timeout <= 0` means return
|
||||
// immediately if no transaction can be performed without waiting.
|
||||
// return value: the index of the channel on which a transaction has taken place
|
||||
// -1 if waiting for a transaction has exceeded timeout
|
||||
// -2 if all channels are closed
|
||||
|
@ -646,7 +646,11 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo
|
|||
C.atomic_store_u16(&ch.read_sub_mtx, u16(0))
|
||||
}
|
||||
}
|
||||
stopwatch := if timeout <= 0 { time.StopWatch{} } else { time.new_stopwatch({}) }
|
||||
stopwatch := if timeout == time.infinite || timeout <= 0 {
|
||||
time.StopWatch{}
|
||||
} else {
|
||||
time.new_stopwatch({})
|
||||
}
|
||||
mut event_idx := -1 // negative index means `timed out`
|
||||
|
||||
outer: for {
|
||||
|
@ -679,10 +683,10 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo
|
|||
event_idx = -2
|
||||
break outer
|
||||
}
|
||||
if timeout == 0 {
|
||||
if timeout <= 0 {
|
||||
break outer
|
||||
}
|
||||
if timeout > 0 {
|
||||
if timeout != time.infinite {
|
||||
remaining := timeout - stopwatch.elapsed()
|
||||
if !sem.timed_wait(remaining) {
|
||||
break outer
|
||||
|
|
|
@ -176,7 +176,7 @@ pub fn (mut sem Semaphore) timed_wait(timeout time.Duration) bool {
|
|||
C.GetSystemTimeAsFileTime(&ft_start)
|
||||
time_end := ((u64(ft_start.dwHighDateTime) << 32) | ft_start.dwLowDateTime) +
|
||||
u64(timeout / (100 * time.nanosecond))
|
||||
mut t_ms := u32(timeout / time.millisecond)
|
||||
mut t_ms := timeout.sys_milliseconds()
|
||||
C.AcquireSRWLockExclusive(&sem.mtx)
|
||||
mut res := 0
|
||||
c = C.atomic_load_u32(&sem.count)
|
||||
|
|
|
@ -394,7 +394,7 @@ pub const (
|
|||
second = Duration(1000 * millisecond)
|
||||
minute = Duration(60 * second)
|
||||
hour = Duration(60 * minute)
|
||||
infinite = Duration(-1)
|
||||
infinite = Duration(C.INT64_MAX)
|
||||
)
|
||||
|
||||
// nanoseconds returns the duration as an integer number of nanoseconds.
|
||||
|
|
|
@ -149,3 +149,15 @@ pub fn sleep(duration Duration) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// some *nix system functions (e.g. `C.poll()`, C.epoll_wait()) accept an `int`
|
||||
// value as *timeout in milliseconds* with the special value `-1` meaning "infinite"
|
||||
pub fn (d Duration) sys_milliseconds() int {
|
||||
if d > C.INT32_MAX * millisecond { // treat 2147483647000001 .. C.INT64_MAX as "infinite"
|
||||
return -1
|
||||
} else if d <= 0 {
|
||||
return 0 // treat negative timeouts as 0 - consistent with Unix behaviour
|
||||
} else {
|
||||
return int(d / millisecond)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,3 +225,15 @@ pub fn wait(duration Duration) {
|
|||
pub fn sleep(duration Duration) {
|
||||
C.Sleep(int(duration / millisecond))
|
||||
}
|
||||
|
||||
// some Windows system functions (e.g. `C.WaitForSingleObject()`) accept an `u32`
|
||||
// value as *timeout in milliseconds* with the special value `u32(-1)` meaning "infinite"
|
||||
pub fn (d Duration) sys_milliseconds() u32 {
|
||||
if d >= u32(-1) * millisecond { // treat 4294967295000000 .. C.INT64_MAX as "infinite"
|
||||
return u32(-1)
|
||||
} else if d <= 0 {
|
||||
return 0 // treat negative timeouts as 0 - consistent with Unix behaviour
|
||||
} else {
|
||||
return u32(d / millisecond)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4102,7 +4102,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
|
|||
} else if has_else {
|
||||
g.write('0')
|
||||
} else {
|
||||
g.write('-1')
|
||||
g.write('_const_time__infinite')
|
||||
}
|
||||
g.writeln(');')
|
||||
// free the temps that were created
|
||||
|
|
Loading…
Reference in New Issue