add a revision lock

This commit is contained in:
Niko Matsakis 2018-10-11 08:18:16 -04:00
parent 12deacbbb5
commit 4a8b264b7f

View file

@ -2,6 +2,7 @@ use crate::Database;
use crate::Query;
use crate::QueryFunction;
use log::debug;
use parking_lot::RwLock;
use rustc_hash::FxHasher;
use std::cell::RefCell;
use std::fmt::Write;
@ -31,6 +32,7 @@ where
Runtime {
shared_state: Arc::new(SharedState {
storage: Default::default(),
revision_lock: Default::default(),
revision: Default::default(),
}),
local_state: RefCell::new(LocalState {
@ -79,6 +81,9 @@ where
panic!("increment_revision invoked during a query computation");
}
// To modify the revision, we need the lock.
let _lock = self.shared_state.revision_lock.write();
let old_revision = self.shared_state.revision.fetch_add(1, Ordering::SeqCst);
assert!(old_revision != usize::max_value(), "revision overflow");
let result = Revision {
@ -173,7 +178,18 @@ where
/// State that will be common to all threads (when we support multiple threads)
struct SharedState<DB: Database> {
storage: DB::DatabaseStorage,
// Ideally, this should be `AtomicU64`, but that is currently unstable.
/// This lock must be held (with write permissions) in order to
/// mutate the current revision. This is used to ensure atomicity
/// of modifying the revision with queries that are executing and
/// so forth.
revision_lock: RwLock<()>,
/// Stores the current revision. This is an `AtomicUsize` because it may be
/// *read* at any point without holding the `revision_lock`. Updates, however,
/// require the `revision_lock` to be acquired.
///
/// (Ideally, this should be `AtomicU64`, but that is currently unstable.)
revision: AtomicUsize,
}