diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2015-07-30 01:43:54 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2015-07-30 01:43:54 +0530 |
| commit | b904b452c607e84c1fb7e4b1a5f9ed6cb4e043e6 (patch) | |
| tree | 57a8be42abc195e1508f7b5abb2e454bab4f97a9 /src/libstd | |
| parent | 35d95515f3de27c0e1a7d67893fcad8d0ad6fac9 (diff) | |
| parent | 43b2c4781e5d6e25dedfc480218ceda92d9dffad (diff) | |
| download | rust-b904b452c607e84c1fb7e4b1a5f9ed6cb4e043e6.tar.gz rust-b904b452c607e84c1fb7e4b1a5f9ed6cb4e043e6.zip | |
Rollup merge of #27373 - alexcrichton:fix-wait-timeout-ms, r=brson
The API we're calling requires us to pass an absolute point in time as an argument (`pthread_cond_timedwait`) so we call `gettimeofday` ahead of time to then add the specified duration to. Unfortuantely the current "add the duration" logic forgot to take into account the current time's sub-second precision (e.g. the `tv_usec` field was ignored), causing sub-second duration waits to return spuriously.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/sys/unix/condvar.rs | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index c8708190a2e..beecb445e8d 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -60,21 +60,22 @@ impl Condvar { let r = ffi::gettimeofday(&mut sys_now, ptr::null_mut()); debug_assert_eq!(r, 0); + let nsec = dur.extra_nanos() as libc::c_long + + (sys_now.tv_usec * 1000) as libc::c_long; + let extra = (nsec / 1_000_000_000) as libc::time_t; + let nsec = nsec % 1_000_000_000; let seconds = dur.secs() as libc::time_t; - let timeout = match sys_now.tv_sec.checked_add(seconds) { - Some(sec) => { - libc::timespec { - tv_sec: sec, - tv_nsec: dur.extra_nanos() as libc::c_long, - } - } - None => { - libc::timespec { - tv_sec: <libc::time_t>::max_value(), - tv_nsec: 1_000_000_000 - 1, - } + + let timeout = sys_now.tv_sec.checked_add(extra).and_then(|s| { + s.checked_add(seconds) + }).map(|s| { + libc::timespec { tv_sec: s, tv_nsec: nsec } + }).unwrap_or_else(|| { + libc::timespec { + tv_sec: <libc::time_t>::max_value(), + tv_nsec: 1_000_000_000 - 1, } - }; + }); // And wait! let r = ffi::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex), |
