Skip to content

Commit 0469f1f

Browse files
authored
Rollup merge of rust-lang#148072 - madsmtm:fix-apple-condvar-32bit, r=joboet
Fix compiling `CondVar::wait_timeout` on 32-bit Apple platforms Fixes rust-lang#147776. I feel like there's a cleaner way to write this, but that probably requires further refactoring. The build can be tested with `./x build --target arm64_32-apple-watchos` (or with any other 32-bit Apple target). Tested it works at runtime on an Intel Macbook Pro with macOS 10.12.6, in x86 emulation mode with something similar to `./x test library/std --target x86_64-apple-darwin,i686-apple-darwin`, as well as with a custom test with a timeout of `Duration::from_secs((u32::MAX as u64) + 1)` (which the naive fix would have treated as a duration of 1 second). r? libs CC `@joboet`
2 parents f36290d + 66b992d commit 0469f1f

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

library/std/src/sys/pal/unix/sync/condvar.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use super::Mutex;
22
use crate::cell::UnsafeCell;
33
use crate::pin::Pin;
4+
#[cfg(not(target_os = "nto"))]
5+
use crate::sys::pal::time::TIMESPEC_MAX;
6+
#[cfg(target_os = "nto")]
7+
use crate::sys::pal::time::TIMESPEC_MAX_CAPPED;
48
use crate::time::Duration;
59

610
pub struct Condvar {
@@ -51,10 +55,6 @@ impl Condvar {
5155
/// * `mutex` must be locked by the current thread.
5256
/// * This condition variable may only be used with the same mutex.
5357
pub unsafe fn wait_timeout(&self, mutex: Pin<&Mutex>, dur: Duration) -> bool {
54-
#[cfg(not(target_os = "nto"))]
55-
use crate::sys::pal::time::TIMESPEC_MAX;
56-
#[cfg(target_os = "nto")]
57-
use crate::sys::pal::time::TIMESPEC_MAX_CAPPED;
5858
use crate::sys::pal::time::Timespec;
5959

6060
let mutex = mutex.raw();
@@ -118,10 +118,12 @@ impl Condvar {
118118

119119
let (dur, clamped) = if dur <= MAX_DURATION { (dur, false) } else { (MAX_DURATION, true) };
120120

121-
let timeout = libc::timespec {
122-
// This cannot overflow because of the clamping above.
123-
tv_sec: dur.as_secs() as i64,
124-
tv_nsec: dur.subsec_nanos() as i64,
121+
// This can overflow on 32-bit platforms, but not on 64-bit because of the clamping above.
122+
let timeout = if let Ok(tv_sec) = dur.as_secs().try_into() {
123+
libc::timespec { tv_sec, tv_nsec: dur.subsec_nanos() as _ }
124+
} else {
125+
// This is less than `MAX_DURATION` on 32-bit platforms.
126+
TIMESPEC_MAX
125127
};
126128

127129
let r = unsafe { libc::pthread_cond_timedwait_relative_np(self.raw(), mutex, &timeout) };

0 commit comments

Comments
 (0)