mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-12 08:30:51 +00:00
Use Event API and add docs
This commit is contained in:
parent
5bface5bb9
commit
83482293c6
3 changed files with 28 additions and 27 deletions
|
@ -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.
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue