Check conversion from Duration to timespec in futex_wait.

This commit is contained in:
Mara Bos 2020-09-20 00:17:05 +02:00
parent 2cf0f64722
commit 485f882d77
1 changed files with 11 additions and 12 deletions

View File

@ -1,27 +1,26 @@
#![cfg(any(target_os = "linux", target_os = "android"))] #![cfg(any(target_os = "linux", target_os = "android"))]
use crate::convert::TryInto;
use crate::ptr::null;
use crate::sync::atomic::AtomicI32; use crate::sync::atomic::AtomicI32;
use crate::time::Duration; use crate::time::Duration;
pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) { pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
let timespec; let timespec = timeout.and_then(|d| {
let timespec_ptr = match timeout { Some(libc::timespec {
Some(timeout) => { // Sleep forever if the timeout is longer than fits in a timespec.
timespec = libc::timespec { tv_sec: d.as_secs().try_into().ok()?,
tv_sec: timeout.as_secs() as _, // This conversion never truncates, as subsec_nanos is always <1e9.
tv_nsec: timeout.subsec_nanos() as _, tv_nsec: d.subsec_nanos() as _,
}; })
&timespec as *const libc::timespec });
}
None => crate::ptr::null(),
};
unsafe { unsafe {
libc::syscall( libc::syscall(
libc::SYS_futex, libc::SYS_futex,
futex as *const AtomicI32, futex as *const AtomicI32,
libc::FUTEX_WAIT | libc::FUTEX_PRIVATE_FLAG, libc::FUTEX_WAIT | libc::FUTEX_PRIVATE_FLAG,
expected, expected,
timespec_ptr, timespec.as_ref().map_or(null(), |d| d as *const libc::timespec),
); );
} }
} }