@@ -6,6 +6,8 @@ use nix::sys::signal::*;
66use nix:: sys:: time:: { TimeSpec , TimeValLike } ;
77use std:: io:: { Write , Read , Seek , SeekFrom } ;
88use std:: os:: unix:: io:: AsRawFd ;
9+ use std:: sync:: Mutex ;
10+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
911use std:: { thread, time} ;
1012use tempfile:: tempfile;
1113
@@ -192,22 +194,24 @@ fn test_write() {
192194 assert ! ( rbuf == EXPECT ) ;
193195}
194196
195- // XXX: should be sig_atomic_t, but rust's libc doesn't define that yet
196- static mut SIGNALED : i32 = 0 ;
197+ lazy_static ! {
198+ pub static ref SIGNALED : AtomicBool = AtomicBool :: new( false ) ;
199+ // protects access to SIGUSR2 handlers, not just SIGNALED
200+ pub static ref SIGUSR2_MTX : Mutex <( ) > = Mutex :: new( ( ) ) ;
201+ }
197202
198203extern fn sigfunc ( _: c_int ) {
199- // It's a pity that Rust can't understand that static mutable sig_atomic_t
200- // variables can be safely accessed
201- unsafe { SIGNALED = 1 } ;
204+ SIGNALED . store ( true , Ordering :: Relaxed ) ;
202205}
203206
204207// Test an aio operation with completion delivered by a signal
205208#[ test]
206209fn test_write_sigev_signal ( ) {
210+ let _ = SIGUSR2_MTX . lock ( ) . expect ( "Mutex got poisoned by another test" ) ;
207211 let sa = SigAction :: new ( SigHandler :: Handler ( sigfunc) ,
208212 SA_RESETHAND ,
209213 SigSet :: empty ( ) ) ;
210- unsafe { SIGNALED = 0 } ;
214+ SIGNALED . store ( false , Ordering :: Relaxed ) ;
211215 unsafe { sigaction ( Signal :: SIGUSR2 , & sa) } . unwrap ( ) ;
212216
213217 const INITIAL : & ' static [ u8 ] = b"abcdef123456" ;
@@ -227,7 +231,7 @@ fn test_write_sigev_signal() {
227231 } ,
228232 LioOpcode :: LIO_NOP ) ;
229233 aiocb. write ( ) . unwrap ( ) ;
230- while unsafe { SIGNALED == 0 } {
234+ while SIGNALED . load ( Ordering :: Relaxed ) == false {
231235 thread:: sleep ( time:: Duration :: from_millis ( 10 ) ) ;
232236 }
233237
@@ -329,6 +333,7 @@ fn test_lio_listio_nowait() {
329333#[ test]
330334#[ cfg( not( any( target_os = "ios" , target_os = "macos" ) ) ) ]
331335fn test_lio_listio_signal ( ) {
336+ let _ = SIGUSR2_MTX . lock ( ) . expect ( "Mutex got poisoned by another test" ) ;
332337 const INITIAL : & ' static [ u8 ] = b"abcdef123456" ;
333338 const WBUF : & ' static [ u8 ] = b"CDEF" ;
334339 let mut rbuf = vec ! [ 0 ; 4 ] ;
@@ -357,11 +362,11 @@ fn test_lio_listio_signal() {
357362 0 , //priority
358363 SigevNotify :: SigevNone ,
359364 LioOpcode :: LIO_READ ) ;
360- unsafe { SIGNALED = 0 } ;
365+ SIGNALED . store ( false , Ordering :: Relaxed ) ;
361366 unsafe { sigaction ( Signal :: SIGUSR2 , & sa) } . unwrap ( ) ;
362367 let err = lio_listio ( LioMode :: LIO_NOWAIT , & [ & mut wcb, & mut rcb] , sigev_notify) ;
363368 err. expect ( "lio_listio failed" ) ;
364- while unsafe { SIGNALED == 0 } {
369+ while SIGNALED . load ( Ordering :: Relaxed ) == false {
365370 thread:: sleep ( time:: Duration :: from_millis ( 10 ) ) ;
366371 }
367372
0 commit comments