about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2015-07-30 01:43:54 +0530
committerManish Goregaokar <manishsmail@gmail.com>2015-07-30 01:43:54 +0530
commitb904b452c607e84c1fb7e4b1a5f9ed6cb4e043e6 (patch)
tree57a8be42abc195e1508f7b5abb2e454bab4f97a9 /src/libstd
parent35d95515f3de27c0e1a7d67893fcad8d0ad6fac9 (diff)
parent43b2c4781e5d6e25dedfc480218ceda92d9dffad (diff)
downloadrust-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.rs27
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),