diff --git a/src/executor/flushb.rs b/src/executor/flushb.rs index 4c87a3d5..6e42eb02 100644 --- a/src/executor/flushb.rs +++ b/src/executor/flushb.rs @@ -15,7 +15,9 @@ impl ExecutorFlushB { if let StoreItem(collection, Some(bucket), None) = store { // Important: acquire database access read lock, and reference it in context. This \ // prevents the database from being erased while using it in this block. + // Notice: acquire FST lock in write mode, as we will erase it. general_kv_access_lock_read!(); + general_fst_access_lock_write!(); if let Ok(kv_store) = StoreKVPool::acquire(StoreKVAcquireMode::OpenOnly, collection) { // Important: acquire bucket store write lock diff --git a/src/executor/flushc.rs b/src/executor/flushc.rs index 09aaae78..503da00b 100644 --- a/src/executor/flushc.rs +++ b/src/executor/flushc.rs @@ -16,6 +16,11 @@ impl ExecutorFlushC { // even if dropped in the inner function, as this caller would still own a reference to \ // it. if let StoreItem(collection, None, None) = store { + // Acquire KV + FST locks in write mode, as we will erase them, we need to prevent any \ + // other consumer to use them. + general_kv_access_lock_write!(); + general_fst_access_lock_write!(); + match ( StoreKVActionBuilder::erase(collection, None), StoreFSTActionBuilder::erase(collection, None), diff --git a/src/executor/macros.rs b/src/executor/macros.rs index d1d90efa..2f5f0a41 100644 --- a/src/executor/macros.rs +++ b/src/executor/macros.rs @@ -45,6 +45,15 @@ macro_rules! general_kv_access_lock_read { }; } +#[macro_export] +macro_rules! general_kv_access_lock_write { + () => { + use crate::store::kv::STORE_ACCESS_LOCK; + + let _kv_access = STORE_ACCESS_LOCK.write().unwrap(); + }; +} + #[macro_export] macro_rules! general_fst_access_lock_read { () => { @@ -53,3 +62,12 @@ macro_rules! general_fst_access_lock_read { let _fst_access = GRAPH_ACCESS_LOCK.read().unwrap(); }; } + +#[macro_export] +macro_rules! general_fst_access_lock_write { + () => { + use crate::store::fst::GRAPH_ACCESS_LOCK; + + let _fst_access = GRAPH_ACCESS_LOCK.write().unwrap(); + }; +} diff --git a/src/store/fst.rs b/src/store/fst.rs index 6fd2b246..eaaaccd7 100644 --- a/src/store/fst.rs +++ b/src/store/fst.rs @@ -867,7 +867,7 @@ impl StoreFSTActionBuilder { } pub fn erase<'a, T: Into<&'a str>>(collection: T, bucket: Option) -> Result { - Self::dispatch_erase("fst", collection, bucket, &*GRAPH_ACCESS_LOCK) + Self::dispatch_erase("fst", collection, bucket) } fn build(store: StoreFSTBox) -> StoreFSTAction { diff --git a/src/store/generic.rs b/src/store/generic.rs index 8a0121a7..acf54ba2 100644 --- a/src/store/generic.rs +++ b/src/store/generic.rs @@ -147,16 +147,11 @@ pub trait StoreGenericActionBuilder { kind: &str, collection: T, bucket: Option, - access_lock: &Arc>, ) -> Result { let collection_str = collection.into(); info!("{} erase requested on collection: {}", kind, collection_str); - // Acquire access lock (in blocking write mode), and reference it in context - // Notice: this prevents store to be acquired from any context - let _access = access_lock.write().unwrap(); - if let Some(bucket) = bucket { Self::proceed_erase_bucket(collection_str, bucket.into()) } else { diff --git a/src/store/kv.rs b/src/store/kv.rs index e833292e..ef50bbdd 100644 --- a/src/store/kv.rs +++ b/src/store/kv.rs @@ -397,7 +397,7 @@ impl StoreKVActionBuilder { } pub fn erase<'a, T: Into<&'a str>>(collection: T, bucket: Option) -> Result { - Self::dispatch_erase("kv", collection, bucket, &*STORE_ACCESS_LOCK) + Self::dispatch_erase("kv", collection, bucket) } fn build(bucket: StoreItemPart, store: Option) -> StoreKVAction {