mod common;
use libc::fork;
pub use process_sync::private::SharedMemoryObject;
use process_sync::{private::check_libc_err, SharedCondvar, SharedMutex};
use common::{sleep, TestOutput};
fn child0(test_output: &mut TestOutput, mutex: &mut SharedMutex, condvar: &mut SharedCondvar) -> ! {
test_output.write_line("child0 lock()");
mutex.lock().expect("lock() failed");
test_output.write_line("child0 wait()");
condvar.wait(mutex).expect("wait() failed");
mutex.unlock().expect("unlock() failed");
test_output.write_line("child0 unlocked");
sleep(5);
test_output.write_line("child0 FIRST_TEST_END");
sleep(100);
test_output.write_line("child0 lock()");
mutex.lock().expect("lock() failed");
test_output.write_line("child0 wait()");
condvar.wait(mutex).expect("wait() failed");
test_output.write_line("child0 unlock()");
mutex.unlock().expect("unlock() failed");
test_output.write_line("child0 unlocked");
std::process::exit(0);
}
fn child1(test_output: &mut TestOutput, mutex: &mut SharedMutex, condvar: &mut SharedCondvar) {
sleep(10);
test_output.write_line("child1 lock()");
mutex.lock().expect("lock() failed");
test_output.write_line("child1 wait()");
condvar.wait(mutex).expect("wait() failed");
mutex.unlock().expect("unlock() failed");
sleep(10);
test_output.write_line("child1 unlocked");
test_output.write_line("child1 FIRST_TEST_END");
sleep(50);
test_output.write_line("child1 lock()");
mutex.lock().expect("lock() failed");
test_output.write_line("child1 wait()");
condvar.wait(mutex).expect("wait() failed");
test_output.write_line("child1 unlock()");
mutex.unlock().expect("unlock() failed");
test_output.write_line("child1 unlocked");
std::process::exit(0);
}
fn parent(test_output: &mut TestOutput, _mutex: &mut SharedMutex, condvar: &mut SharedCondvar) {
sleep(40);
test_output.write_line("parent notify_all()");
condvar.notify_all().expect("notify_all() failed");
test_output.write_line("parent FIRST_TEST_END");
sleep(300);
test_output.write_line("parent notify_one()");
condvar.notify_one().expect("notify_one() failed");
sleep(10);
test_output.write_line("parent notify_one()");
condvar.notify_one().expect("notify_one() failed");
sleep(40);
}
fn main() {
let mut test_output = TestOutput::new(&[
"child0 lock()",
"child0 wait()",
"child1 lock()",
"child1 wait()",
"parent notify_all()",
"parent FIRST_TEST_END",
"child0 unlocked",
"child0 FIRST_TEST_END",
"child1 unlocked",
"child1 FIRST_TEST_END",
"child1 lock()",
"child1 wait()",
"child0 lock()",
"child0 wait()",
"parent notify_one()",
"child1 unlock()",
"child1 unlocked",
"parent notify_one()",
"child0 unlock()",
"child0 unlocked",
]);
let mut mutex = SharedMutex::new().expect("cannot create SharedMutex");
let mut condvar = SharedCondvar::new().expect("cannot create SharedCondvar");
let pid = check_libc_err(unsafe { fork() }).expect("fork failed");
if pid == 0 {
child0(&mut test_output, &mut mutex, &mut condvar);
} else {
let pid = check_libc_err(unsafe { fork() }).expect("fork failed");
if pid == 0 {
child1(&mut test_output, &mut mutex, &mut condvar);
} else {
parent(&mut test_output, &mut mutex, &mut condvar);
}
}
}