Round up when converting timeout to ms for epoll_wait()
@@ -87,7 +87,19 @@ impl Selector {
const MAX_SAFE_TIMEOUT: u128 = libc::c_int::max_value() as u128;
let timeout = timeout
- .map(|to| cmp::min(to.as_millis(), MAX_SAFE_TIMEOUT) as libc::c_int)
+ .map(|to| {
+ let to_ms = to.as_millis();
+ // as_millis() truncates, so round up to 1 ms as the documentation says can happen.
+ // This avoids turning submillisecond timeouts into immediate returns unless the
+ // caller explicitly requests that by specifying a zero timeout.
+ let to_ms = to_ms
+ + if to_ms == 0 && to.subsec_nanos() != 0 {
+ 1
+ } else {
+ 0
+ };
+ cmp::min(MAX_SAFE_TIMEOUT, to_ms) as libc::c_int
+ })
.unwrap_or(-1);
events.clear();
