Use Event API and add docs

This commit is contained in:
Kevin Leimkuhler 2018-10-31 12:01:30 -07:00
parent 5bface5bb9
commit 83482293c6
3 changed files with 28 additions and 27 deletions

View file

@ -628,38 +628,32 @@ where
// panicked before it could be removed. At this point, we
// therefore "own" unique access to our slot, so we can just
// remove the `InProgress` marker.
let waiting = {
let mut map = self.map.write();
match map.remove(self.key) {
Some(QueryState::InProgress { id, waiting }) => {
assert_eq!(id, self.my_id);
let mut map = self.map.write();
match map.remove(self.key) {
Some(QueryState::InProgress { id, waiting }) => {
assert_eq!(id, self.my_id);
let waiting = waiting.into_inner();
let waiting = waiting.into_inner();
if waiting.is_empty() {
// if nobody is waiting, we are done here
return;
} else {
waiting
}
if !waiting.is_empty() {
// We want to propagate our panic to those waiting on
// us. By dropping `waiting`, others will panic in
// `.recv`.
std::mem::drop(waiting)
}
}
// If we don't see an `InProgress` marker, something
// has gone horribly wrong. This panic will
// (unfortunately) abort the process, but recovery is
// not possible.
_ => panic!(
"\
// If we don't see an `InProgress` marker, something
// has gone horribly wrong. This panic will
// (unfortunately) abort the process, but recovery is
// not possible.
_ => panic!(
"\
Unexpected panic during query evaluation, aborting the process.
Please report this bug to https://github.com/salsa-rs/salsa/issues."
),
}
};
// We want to propagate our panic to those waiting on us. By dropping
// `waiting`, others will panic in `.recv`.
std::mem::drop(waiting)
),
}
} else {
// If no panic occurred, then panic guard ought to be
// "forgotten" and so this Drop code should never run.

View file

@ -112,7 +112,7 @@ where
/// Check if `key` is (currently) believed to be a constant.
fn is_constant(&self, db: &DB, key: &Q::Key) -> bool;
/// Check if `key` is (currently) believed to be a constant.
/// Get the (current) set of the keys in the query storage
fn keys<C>(&self, db: &DB) -> C
where
C: std::iter::FromIterator<Q::Key>;

View file

@ -84,12 +84,17 @@ fn true_parallel_same_keys() {
assert_eq!(thread2.join().unwrap(), 111);
}
/// Add a test that tries to trigger a conflict, where we fetch `sum("a")`
/// from two threads simultaneously. After `thread2` begins blocking,
/// we force `thread1` to panic and should see that propagate to `thread2`.
#[test]
fn true_parallel_propagate_panic() {
let db = ParDatabaseImpl::default();
db.query(Input).set('a', 1);
// `thread1` will wait_for a barrier in the start of `sum`. Once it can
// continue, it will panic.
let thread1 = std::thread::spawn({
let db = db.fork();
move || {
@ -102,11 +107,13 @@ fn true_parallel_propagate_panic() {
}
});
// `thread2` will wait until `thread1` has entered sum and then -- once it
// has set itself to block -- signal `thread1` to continue.
let thread2 = std::thread::spawn({
let db = db.fork();
move || {
db.knobs().signal.wait_for(1);
db.knobs().signal.signal(2);
db.knobs().signal_on_will_block.set(2);
db.sum("a")
}
});