mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-23 13:10:19 +00:00
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:
parent
da94eae920
commit
add15d83ea
3 changed files with 18 additions and 2 deletions
|
@ -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))
|
ProbeState::UpToDate(Ok(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,7 +731,7 @@ where
|
||||||
// can complete.
|
// can complete.
|
||||||
std::mem::drop(map);
|
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);
|
return value.changed_at.changed_since(revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,12 @@ pub trait Database: plumbing::DatabaseStorageTypes + plumbing::DatabaseOps {
|
||||||
fn salsa_event(&self, event_fn: impl Fn() -> Event<Self>) {
|
fn salsa_event(&self, event_fn: impl Fn() -> Event<Self>) {
|
||||||
#![allow(unused_variables)]
|
#![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
|
/// The `Event` struct identifies various notable things that can
|
||||||
|
|
|
@ -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
|
/// Acquires the **global query write lock** (ensuring that no
|
||||||
/// queries are executing) and then increments the current
|
/// queries are executing) and then increments the current
|
||||||
/// revision counter; invokes `op` with the global query write
|
/// revision counter; invokes `op` with the global query write
|
||||||
|
|
Loading…
Reference in a new issue