@@ -6,6 +6,8 @@ use nix::sys::signal::*;
6
6
use nix:: sys:: time:: { TimeSpec , TimeValLike } ;
7
7
use std:: io:: { Write , Read , Seek , SeekFrom } ;
8
8
use std:: os:: unix:: io:: AsRawFd ;
9
+ use std:: sync:: Mutex ;
10
+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
9
11
use std:: { thread, time} ;
10
12
use tempfile:: tempfile;
11
13
@@ -192,22 +194,24 @@ fn test_write() {
192
194
assert ! ( rbuf == EXPECT ) ;
193
195
}
194
196
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
+ }
197
202
198
203
extern 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 ) ;
202
205
}
203
206
204
207
// Test an aio operation with completion delivered by a signal
205
208
#[ test]
206
209
fn test_write_sigev_signal ( ) {
210
+ let _ = SIGUSR2_MTX . lock ( ) . expect ( "Mutex got poisoned by another test" ) ;
207
211
let sa = SigAction :: new ( SigHandler :: Handler ( sigfunc) ,
208
212
SA_RESETHAND ,
209
213
SigSet :: empty ( ) ) ;
210
- unsafe { SIGNALED = 0 } ;
214
+ SIGNALED . store ( false , Ordering :: Relaxed ) ;
211
215
unsafe { sigaction ( Signal :: SIGUSR2 , & sa) } . unwrap ( ) ;
212
216
213
217
const INITIAL : & ' static [ u8 ] = b"abcdef123456" ;
@@ -227,7 +231,7 @@ fn test_write_sigev_signal() {
227
231
} ,
228
232
LioOpcode :: LIO_NOP ) ;
229
233
aiocb. write ( ) . unwrap ( ) ;
230
- while unsafe { SIGNALED == 0 } {
234
+ while SIGNALED . load ( Ordering :: Relaxed ) == false {
231
235
thread:: sleep ( time:: Duration :: from_millis ( 10 ) ) ;
232
236
}
233
237
@@ -329,6 +333,7 @@ fn test_lio_listio_nowait() {
329
333
#[ test]
330
334
#[ cfg( not( any( target_os = "ios" , target_os = "macos" ) ) ) ]
331
335
fn test_lio_listio_signal ( ) {
336
+ let _ = SIGUSR2_MTX . lock ( ) . expect ( "Mutex got poisoned by another test" ) ;
332
337
const INITIAL : & ' static [ u8 ] = b"abcdef123456" ;
333
338
const WBUF : & ' static [ u8 ] = b"CDEF" ;
334
339
let mut rbuf = vec ! [ 0 ; 4 ] ;
@@ -357,11 +362,11 @@ fn test_lio_listio_signal() {
357
362
0 , //priority
358
363
SigevNotify :: SigevNone ,
359
364
LioOpcode :: LIO_READ ) ;
360
- unsafe { SIGNALED = 0 } ;
365
+ SIGNALED . store ( false , Ordering :: Relaxed ) ;
361
366
unsafe { sigaction ( Signal :: SIGUSR2 , & sa) } . unwrap ( ) ;
362
367
let err = lio_listio ( LioMode :: LIO_NOWAIT , & [ & mut wcb, & mut rcb] , sigev_notify) ;
363
368
err. expect ( "lio_listio failed" ) ;
364
- while unsafe { SIGNALED == 0 } {
369
+ while SIGNALED . load ( Ordering :: Relaxed ) == false {
365
370
thread:: sleep ( time:: Duration :: from_millis ( 10 ) ) ;
366
371
}
367
372
0 commit comments