track whether a query is in progress more accurately

This commit is contained in:
Niko Matsakis 2018-10-15 05:24:36 -04:00
parent 9d60b1e1cd
commit 04288dadef
2 changed files with 39 additions and 5 deletions

View file

@ -560,6 +560,12 @@ where
let runtime = db.salsa_runtime();
let revision_now = runtime.current_revision();
// If a query is in progress, we know that the current
// revision is not changing.
if !runtime.query_in_progress() {
panic!("maybe_changed_since invoked outside of query execution")
}
debug!(
"{:?}({:?})::maybe_changed_since(revision={:?}, revision_now={:?})",
Q::default(),

View file

@ -88,10 +88,13 @@ where
/// (However, if other threads invoke `increment_revision`, then
/// the current revision may be considered cancelled, which can be
/// observed through `is_current_revision_canceled`.)
pub(crate) fn freeze_revision(&self) -> Option<RwLockReadGuard<'_, ()>> {
let local_state = self.local_state.borrow();
if local_state.query_stack.is_empty() {
Some(self.shared_state.query_lock.read())
pub(crate) fn freeze_revision(&self) -> Option<RevisionGuard<'_, DB>> {
let mut local_state = self.local_state.borrow_mut();
if !local_state.query_in_progress {
local_state.query_in_progress = true;
let guard = self.shared_state.query_lock.read();
Some(RevisionGuard::new(self, guard))
} else {
None
}
@ -136,7 +139,7 @@ where
pub(crate) fn increment_revision(&self) -> Revision {
log::debug!("increment_revision()");
if !self.local_state.borrow().query_stack.is_empty() {
if self.query_in_progress() {
panic!("increment_revision invoked during a query computation");
}
@ -181,6 +184,10 @@ where
result
}
pub(crate) fn query_in_progress(&self) -> bool {
self.local_state.borrow().query_in_progress
}
pub(crate) fn execute_query_implementation<V>(
&self,
descriptor: &DB::QueryDescriptor,
@ -347,17 +354,38 @@ impl<DB: Database> Default for SharedState<DB> {
/// State that will be specific to a single execution threads (when we
/// support multiple threads)
struct LocalState<DB: Database> {
query_in_progress: bool,
query_stack: Vec<ActiveQuery<DB>>,
}
impl<DB: Database> Default for LocalState<DB> {
fn default() -> Self {
LocalState {
query_in_progress: false,
query_stack: Default::default(),
}
}
}
pub(crate) struct RevisionGuard<'db, DB: Database + 'db> {
db: &'db Runtime<DB>,
lock: RwLockReadGuard<'db, ()>,
}
impl<'db, DB: Database> RevisionGuard<'db, DB> {
fn new(db: &'db Runtime<DB>, lock: RwLockReadGuard<'db, ()>) -> Self {
Self { db, lock }
}
}
impl<'db, DB: Database> Drop for RevisionGuard<'db, DB> {
fn drop(&mut self) {
let mut local_state = self.db.local_state.borrow_mut();
assert!(local_state.query_in_progress);
local_state.query_in_progress = false;
}
}
struct ActiveQuery<DB: Database> {
/// What query is executing
descriptor: DB::QueryDescriptor,