about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2020-09-20 00:17:05 +0200
committerMara Bos <m-ou.se@m-ou.se>2020-09-27 11:56:43 +0200
commit485f882d7713b0e0b864fc8b21368910e5b8b0a7 (patch)
tree6c6f69b0731b366700885bd2c74a06bf5c51ac56 /library/std/src
parent2cf0f64722a92dffa12d43a4c0383a9d76becbcc (diff)
downloadrust-485f882d7713b0e0b864fc8b21368910e5b8b0a7.tar.gz
rust-485f882d7713b0e0b864fc8b21368910e5b8b0a7.zip
Check conversion from Duration to timespec in futex_wait.
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/sys/unix/futex.rs23
1 files changed, 11 insertions, 12 deletions
diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs
index 6af06aa5f7e..e6f0c48c59b 100644
--- a/library/std/src/sys/unix/futex.rs
+++ b/library/std/src/sys/unix/futex.rs
@@ -1,27 +1,26 @@
 #![cfg(any(target_os = "linux", target_os = "android"))]
 
+use crate::convert::TryInto;
+use crate::ptr::null;
 use crate::sync::atomic::AtomicI32;
 use crate::time::Duration;
 
 pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
-    let timespec;
-    let timespec_ptr = match timeout {
-        Some(timeout) => {
-            timespec = libc::timespec {
-                tv_sec: timeout.as_secs() as _,
-                tv_nsec: timeout.subsec_nanos() as _,
-            };
-            &timespec as *const libc::timespec
-        }
-        None => crate::ptr::null(),
-    };
+    let timespec = timeout.and_then(|d| {
+        Some(libc::timespec {
+            // Sleep forever if the timeout is longer than fits in a timespec.
+            tv_sec: d.as_secs().try_into().ok()?,
+            // This conversion never truncates, as subsec_nanos is always <1e9.
+            tv_nsec: d.subsec_nanos() as _,
+        })
+    });
     unsafe {
         libc::syscall(
             libc::SYS_futex,
             futex as *const AtomicI32,
             libc::FUTEX_WAIT | libc::FUTEX_PRIVATE_FLAG,
             expected,
-            timespec_ptr,
+            timespec.as_ref().map_or(null(), |d| d as *const libc::timespec),
         );
     }
 }