Skip to content

Commit 8c47de4

Browse files
committed
Merge #579
579: tests should protect concurrent access to signal handlers r=asomers Adds a mutex to protect access to SIGUSR2 signal handlers by the AIO tests. Fixes #578
2 parents 6a05ee0 + 46ed256 commit 8c47de4

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ cfg-if = "0.1.0"
2828
void = "1.0.2"
2929

3030
[dev-dependencies]
31+
lazy_static = "0.2"
3132
rand = "0.3.8"
3233
tempdir = "0.3"
3334
tempfile = "2"

test/sys/test_aio.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use nix::sys::signal::*;
66
use nix::sys::time::{TimeSpec, TimeValLike};
77
use std::io::{Write, Read, Seek, SeekFrom};
88
use std::os::unix::io::AsRawFd;
9+
use std::sync::Mutex;
10+
use std::sync::atomic::{AtomicBool, Ordering};
911
use std::{thread, time};
1012
use 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

198203
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);
202205
}
203206

204207
// Test an aio operation with completion delivered by a signal
205208
#[test]
206209
fn 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")))]
331335
fn 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

test/test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#[macro_use]
22
extern crate nix;
3+
#[macro_use]
4+
extern crate lazy_static;
35
extern crate libc;
46
extern crate rand;
57
extern crate tempdir;

0 commit comments

Comments
 (0)