@@ -26,6 +26,7 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
26
26
use super :: time:: Timespec ;
27
27
use crate :: ptr:: null;
28
28
use crate :: sync:: atomic:: Ordering :: Relaxed ;
29
+ use crate :: sys:: cvt;
29
30
30
31
// Calculate the timeout as an absolute timespec.
31
32
//
@@ -40,7 +41,7 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
40
41
return true ;
41
42
}
42
43
43
- let r = unsafe {
44
+ let r = cvt ( unsafe {
44
45
cfg_if:: cfg_if! {
45
46
if #[ cfg( target_os = "freebsd" ) ] {
46
47
// FreeBSD doesn't have futex(), but it has
@@ -77,12 +78,16 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
77
78
compile_error!( "unknown target_os" ) ;
78
79
}
79
80
}
80
- } ;
81
-
82
- match ( r < 0 ) . then ( super :: os:: errno) {
83
- Some ( libc:: ETIMEDOUT ) => return false ,
84
- Some ( libc:: EINTR ) => continue ,
85
- _ => return true ,
81
+ } ) ;
82
+
83
+ match r {
84
+ Ok ( _) => return true ,
85
+ Err ( e) => match e. raw_os_error ( ) {
86
+ Some ( libc:: ETIMEDOUT ) => return false ,
87
+ Some ( libc:: EINTR ) => continue ,
88
+ Some ( libc:: EAGAIN ) => return true ,
89
+ _ => panic ! ( "failed to wait on futex: {e:?}" ) ,
90
+ } ,
86
91
}
87
92
}
88
93
}
@@ -95,19 +100,22 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
95
100
/// On some platforms, this always returns false.
96
101
#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
97
102
pub fn futex_wake ( futex : & AtomicU32 ) -> bool {
103
+ use crate :: sys:: cvt;
98
104
let ptr = futex as * const AtomicU32 ;
99
105
let op = libc:: FUTEX_WAKE | libc:: FUTEX_PRIVATE_FLAG ;
100
- unsafe { libc:: syscall ( libc:: SYS_futex , ptr, op, 1 ) > 0 }
106
+ cvt ( unsafe { libc:: syscall ( libc:: SYS_futex , ptr, op, 1 ) } )
107
+ . expect ( "failed to wake futex waiters" )
108
+ > 0
101
109
}
102
110
103
111
/// Wakes up all threads that are waiting on `futex_wait` on this futex.
104
112
#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
105
113
pub fn futex_wake_all ( futex : & AtomicU32 ) {
114
+ use crate :: sys:: cvt;
106
115
let ptr = futex as * const AtomicU32 ;
107
116
let op = libc:: FUTEX_WAKE | libc:: FUTEX_PRIVATE_FLAG ;
108
- unsafe {
109
- libc:: syscall ( libc:: SYS_futex , ptr, op, i32:: MAX ) ;
110
- }
117
+ cvt ( unsafe { libc:: syscall ( libc:: SYS_futex , ptr, op, i32:: MAX ) } )
118
+ . expect ( "failed to wake futex waiters" ) ;
111
119
}
112
120
113
121
// FreeBSD doesn't tell us how many threads are woken up, so this always returns false.
0 commit comments