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
|
// infinite_timeout should be given to functions when an infinite_timeout is wanted (i.e. functions
|
||||||
// only ever return with data)
|
// 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
|
// Shutdown shutsdown a socket and closes it
|
||||||
fn shutdown(handle int) ? {
|
fn shutdown(handle int) ? {
|
||||||
|
@ -34,7 +34,7 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool {
|
||||||
C.FD_ZERO(&set)
|
C.FD_ZERO(&set)
|
||||||
C.FD_SET(handle, &set)
|
C.FD_SET(handle, &set)
|
||||||
|
|
||||||
seconds := timeout.milliseconds() / 1000
|
seconds := timeout / time.second
|
||||||
microseconds := time.Duration(timeout - (seconds * time.second)).microseconds()
|
microseconds := time.Duration(timeout - (seconds * time.second)).microseconds()
|
||||||
|
|
||||||
mut tt := C.timeval{
|
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
|
// wait_for_common wraps the common wait code
|
||||||
fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ? {
|
fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ? {
|
||||||
if deadline.unix == 0 {
|
if deadline.unix == 0 {
|
||||||
// only accept infinite_timeout as a valid
|
// do not accept negative timeout
|
||||||
// negative timeout - it is handled in @select however
|
if timeout < 0 {
|
||||||
if timeout < 0 && timeout != net.infinite_timeout {
|
|
||||||
return err_timed_out
|
return err_timed_out
|
||||||
}
|
}
|
||||||
ready := select_with_retry(handle, test, timeout) ?
|
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_ZERO(&set)
|
||||||
C.FD_SET(handle, &set)
|
C.FD_SET(handle, &set)
|
||||||
|
|
||||||
seconds := timeout.milliseconds() / 1000
|
seconds := timeout / time.second
|
||||||
microseconds := timeout - (seconds * time.second)
|
microseconds := time.Duration(timeout - (seconds * time.second)).microseconds()
|
||||||
|
|
||||||
mut tt := C.timeval{
|
mut tt := C.timeval{
|
||||||
tv_sec: u64(seconds)
|
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
|
// wait_for_common wraps the common wait code
|
||||||
fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ? {
|
fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ? {
|
||||||
if deadline.unix == 0 {
|
if deadline.unix == 0 {
|
||||||
// only accept infinite_timeout as a valid
|
// do not accept negative timeout
|
||||||
// negative timeout - it is handled in @select however
|
if timeout < 0 {
|
||||||
if timeout < 0 && timeout != unix.infinite_timeout {
|
|
||||||
return net.err_timed_out
|
return net.err_timed_out
|
||||||
}
|
}
|
||||||
ready := @select(handle, test, timeout) ?
|
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
|
// infinite_timeout should be given to functions when an infinite_timeout is wanted (i.e. functions
|
||||||
// only ever return with data)
|
// only ever return with data)
|
||||||
const (
|
const (
|
||||||
infinite_timeout = time.Duration(-1)
|
infinite_timeout = time.infinite
|
||||||
)
|
)
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
|
|
|
@ -107,10 +107,7 @@ fn (mut en EpollNotifier) wait(timeout time.Duration) []FdEvent {
|
||||||
// the added bonus of making EpollNotifier thread safe
|
// the added bonus of making EpollNotifier thread safe
|
||||||
events := [512]C.epoll_event{}
|
events := [512]C.epoll_event{}
|
||||||
// populate events with the new events
|
// populate events with the new events
|
||||||
to := match timeout {
|
to := timeout.sys_milliseconds()
|
||||||
time.infinite { -1 }
|
|
||||||
else { int(timeout / time.millisecond) }
|
|
||||||
}
|
|
||||||
count := C.epoll_wait(en.epoll_fd, &events[0], events.len, to)
|
count := C.epoll_wait(en.epoll_fd, &events[0], events.len, to)
|
||||||
|
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
module sync
|
module sync
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
fn do_rec_i64(mut ch Channel) {
|
fn do_rec_i64(mut ch Channel) {
|
||||||
mut sum := i64(0)
|
mut sum := i64(0)
|
||||||
for _ in 0 .. 300 {
|
for _ in 0 .. 300 {
|
||||||
|
@ -56,7 +58,7 @@ fn test_select() {
|
||||||
mut sl := i64(0)
|
mut sl := i64(0)
|
||||||
mut objs := [voidptr(&ri), &sl, &rl, &rb]
|
mut objs := [voidptr(&ri), &sl, &rl, &rb]
|
||||||
for _ in 0 .. 1200 {
|
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 {
|
match idx {
|
||||||
0 {
|
0 {
|
||||||
sum += ri
|
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`)
|
// 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
|
// object referenced by `objrefs[i]`. `timeout = time.infinite` means wait unlimited time. `timeout <= 0` means return
|
||||||
// if no transaction can be performed without waiting.
|
// immediately if no transaction can be performed without waiting.
|
||||||
// return value: the index of the channel on which a transaction has taken place
|
// return value: the index of the channel on which a transaction has taken place
|
||||||
// -1 if waiting for a transaction has exceeded timeout
|
// -1 if waiting for a transaction has exceeded timeout
|
||||||
// -2 if all channels are closed
|
// -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))
|
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`
|
mut event_idx := -1 // negative index means `timed out`
|
||||||
|
|
||||||
outer: for {
|
outer: for {
|
||||||
|
@ -679,10 +683,10 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo
|
||||||
event_idx = -2
|
event_idx = -2
|
||||||
break outer
|
break outer
|
||||||
}
|
}
|
||||||
if timeout == 0 {
|
if timeout <= 0 {
|
||||||
break outer
|
break outer
|
||||||
}
|
}
|
||||||
if timeout > 0 {
|
if timeout != time.infinite {
|
||||||
remaining := timeout - stopwatch.elapsed()
|
remaining := timeout - stopwatch.elapsed()
|
||||||
if !sem.timed_wait(remaining) {
|
if !sem.timed_wait(remaining) {
|
||||||
break outer
|
break outer
|
||||||
|
|
|
@ -176,7 +176,7 @@ pub fn (mut sem Semaphore) timed_wait(timeout time.Duration) bool {
|
||||||
C.GetSystemTimeAsFileTime(&ft_start)
|
C.GetSystemTimeAsFileTime(&ft_start)
|
||||||
time_end := ((u64(ft_start.dwHighDateTime) << 32) | ft_start.dwLowDateTime) +
|
time_end := ((u64(ft_start.dwHighDateTime) << 32) | ft_start.dwLowDateTime) +
|
||||||
u64(timeout / (100 * time.nanosecond))
|
u64(timeout / (100 * time.nanosecond))
|
||||||
mut t_ms := u32(timeout / time.millisecond)
|
mut t_ms := timeout.sys_milliseconds()
|
||||||
C.AcquireSRWLockExclusive(&sem.mtx)
|
C.AcquireSRWLockExclusive(&sem.mtx)
|
||||||
mut res := 0
|
mut res := 0
|
||||||
c = C.atomic_load_u32(&sem.count)
|
c = C.atomic_load_u32(&sem.count)
|
||||||
|
|
|
@ -394,7 +394,7 @@ pub const (
|
||||||
second = Duration(1000 * millisecond)
|
second = Duration(1000 * millisecond)
|
||||||
minute = Duration(60 * second)
|
minute = Duration(60 * second)
|
||||||
hour = Duration(60 * minute)
|
hour = Duration(60 * minute)
|
||||||
infinite = Duration(-1)
|
infinite = Duration(C.INT64_MAX)
|
||||||
)
|
)
|
||||||
|
|
||||||
// nanoseconds returns the duration as an integer number of nanoseconds.
|
// 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) {
|
pub fn sleep(duration Duration) {
|
||||||
C.Sleep(int(duration / millisecond))
|
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 {
|
} else if has_else {
|
||||||
g.write('0')
|
g.write('0')
|
||||||
} else {
|
} else {
|
||||||
g.write('-1')
|
g.write('_const_time__infinite')
|
||||||
}
|
}
|
||||||
g.writeln(');')
|
g.writeln(');')
|
||||||
// free the temps that were created
|
// free the temps that were created
|
||||||
|
|
Loading…
Reference in New Issue