add panic hooks

To implement cancellation via unwinding, one needs to throw `Canceled`
value in `if_current_revision_is_canceled` and `on_propagated_panic`.
This commit is contained in:
Aleksey Kladov 2019-01-10 11:57:24 +03:00
parent da94eae920
commit add15d83ea
3 changed files with 18 additions and 2 deletions

View file

@ -480,7 +480,7 @@ where
},
});
let value = rx.recv().unwrap();
let value = rx.recv().unwrap_or_else(|_| db.on_propagated_panic());
ProbeState::UpToDate(Ok(value))
}
@ -731,7 +731,7 @@ where
// can complete.
std::mem::drop(map);
let value = rx.recv().unwrap();
let value = rx.recv().unwrap_or_else(|_| db.on_propagated_panic());
return value.changed_at.changed_since(revision);
}

View file

@ -104,6 +104,12 @@ pub trait Database: plumbing::DatabaseStorageTypes + plumbing::DatabaseOps {
fn salsa_event(&self, event_fn: impl Fn() -> Event<Self>) {
#![allow(unused_variables)]
}
/// This function is invoked when a depndent query is being computed by the
/// other thread, and that thread panics.
fn on_propagated_panic(&self) -> ! {
panic!("concurrent salsa query paniced")
}
}
/// The `Event` struct identifies various notable things that can

View file

@ -223,6 +223,16 @@ where
}
}
/// Calls the callback if the current revision is cancelled.
///
/// Observing cancellation may lead to inconsistencies in database storage,
/// so the callback must panic.
pub fn if_current_revision_is_canceled(&self, cb: fn() -> !) {
if self.pending_revision() > self.current_revision() {
cb()
}
}
/// Acquires the **global query write lock** (ensuring that no
/// queries are executing) and then increments the current
/// revision counter; invokes `op` with the global query write