2019-01-27 21:06:14 +00:00
|
|
|
use crate::setup::{ParDatabase, ParDatabaseImpl};
|
2018-10-19 09:59:30 +00:00
|
|
|
use crate::signal::Signal;
|
|
|
|
use salsa::{Database, ParallelDatabase};
|
2021-05-17 16:59:28 +00:00
|
|
|
use std::{
|
|
|
|
panic::{catch_unwind, AssertUnwindSafe},
|
|
|
|
sync::Arc,
|
|
|
|
};
|
2018-10-19 09:59:30 +00:00
|
|
|
|
2021-05-25 13:08:23 +00:00
|
|
|
/// Add test where a call to `sum` is cancelled by a simultaneous
|
2018-10-19 09:59:30 +00:00
|
|
|
/// write. Check that we recompute the result in next revision, even
|
|
|
|
/// though none of the inputs have changed.
|
|
|
|
#[test]
|
2021-05-25 13:08:23 +00:00
|
|
|
fn in_par_get_set_cancellation() {
|
2018-11-01 08:30:54 +00:00
|
|
|
let mut db = ParDatabaseImpl::default();
|
2018-10-19 09:59:30 +00:00
|
|
|
|
2019-01-27 21:06:14 +00:00
|
|
|
db.set_input('a', 1);
|
2018-10-19 09:59:30 +00:00
|
|
|
|
|
|
|
let signal = Arc::new(Signal::default());
|
|
|
|
|
|
|
|
let thread1 = std::thread::spawn({
|
2018-11-01 00:05:31 +00:00
|
|
|
let db = db.snapshot();
|
2018-10-19 09:59:30 +00:00
|
|
|
let signal = signal.clone();
|
|
|
|
move || {
|
2021-05-25 13:08:23 +00:00
|
|
|
// Check that cancellation flag is not yet set, because
|
2018-10-19 09:59:30 +00:00
|
|
|
// `set` cannot have been called yet.
|
2021-05-25 13:34:57 +00:00
|
|
|
catch_unwind(AssertUnwindSafe(|| db.unwind_if_cancelled())).unwrap();
|
2018-10-19 09:59:30 +00:00
|
|
|
|
|
|
|
// Signal other thread to proceed.
|
|
|
|
signal.signal(1);
|
|
|
|
|
2021-05-25 13:08:23 +00:00
|
|
|
// Wait for other thread to signal cancellation
|
2021-05-17 16:59:28 +00:00
|
|
|
catch_unwind(AssertUnwindSafe(|| loop {
|
2021-05-25 13:34:57 +00:00
|
|
|
db.unwind_if_cancelled();
|
2018-10-19 09:59:30 +00:00
|
|
|
std::thread::yield_now();
|
2021-05-17 16:59:28 +00:00
|
|
|
}))
|
|
|
|
.unwrap_err();
|
2018-10-19 09:59:30 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let thread2 = std::thread::spawn({
|
|
|
|
move || {
|
2021-05-25 13:08:23 +00:00
|
|
|
// Wait until thread 1 has asserted that they are not cancelled
|
2018-10-19 09:59:30 +00:00
|
|
|
// before we invoke `set.`
|
|
|
|
signal.wait_for(1);
|
|
|
|
|
|
|
|
// This will block until thread1 drops the revision lock.
|
2022-06-03 09:49:23 +00:00
|
|
|
let value = db.remove_input('a') + 1;
|
|
|
|
db.set_input('a', value);
|
2018-10-19 09:59:30 +00:00
|
|
|
|
|
|
|
db.input('a')
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-05-25 12:55:38 +00:00
|
|
|
thread1.join().unwrap();
|
2018-10-19 09:59:30 +00:00
|
|
|
|
|
|
|
let c = thread2.join().unwrap();
|
|
|
|
assert_eq!(c, 2);
|
|
|
|
}
|