Recover from poisoning of internal cache locks

Since they only contain cached values, it's reasonable to overwrite the
value with a new empty map and go from there.

This doesn't affect the lock used in the FFI layer because that protects
caller-provided state, and it doesn't change the function return types
to avoid breaking backwards compatibility.
This commit is contained in:
Oliver Hamlet
2025-03-26 18:11:37 +00:00
parent 7871fcf176
commit 537718766b
2 changed files with 28 additions and 9 deletions
+16 -7
View File
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::{read_dir, DirEntry, File};
use std::hash::Hasher;
@@ -208,10 +209,14 @@ fn evaluate_checksum(state: &State, file_path: &Path, crc: u32) -> Result<bool,
}
let calculated_crc = hasher.finalize();
if let Ok(mut writer) = state.crc_cache.write() {
if let Some(key) = lowercase(file_path) {
writer.insert(key, calculated_crc);
}
let mut writer = state.crc_cache.write().unwrap_or_else(|mut e| {
**e.get_mut() = HashMap::new();
state.crc_cache.clear_poison();
e.into_inner()
});
if let Some(key) = lowercase(file_path) {
writer.insert(key, calculated_crc);
}
Ok(calculated_crc == crc)
@@ -352,9 +357,13 @@ impl Function {
if self.is_slow() {
if let Ok(function_result) = result {
if let Ok(mut writer) = state.condition_cache.write() {
writer.insert(self.clone(), function_result);
}
let mut writer = state.condition_cache.write().unwrap_or_else(|mut e| {
**e.get_mut() = HashMap::new();
state.condition_cache.clear_poison();
e.into_inner()
});
writer.insert(self.clone(), function_result);
}
}
+12 -2
View File
@@ -117,7 +117,11 @@ impl State {
&mut self,
plugin_crcs: &[(T, u32)],
) -> Result<(), PoisonError<RwLockWriteGuard<HashMap<String, u32>>>> {
let mut writer = self.crc_cache.write()?;
let mut writer = self.crc_cache.write().unwrap_or_else(|mut e| {
**e.get_mut() = HashMap::new();
self.crc_cache.clear_poison();
e.into_inner()
});
writer.deref_mut().clear();
writer.deref_mut().extend(
@@ -132,7 +136,13 @@ impl State {
pub fn clear_condition_cache(
&mut self,
) -> Result<(), PoisonError<RwLockWriteGuard<HashMap<Function, bool>>>> {
self.condition_cache.write().map(|mut c| c.clear())
let mut writer = self.condition_cache.write().unwrap_or_else(|mut e| {
**e.get_mut() = HashMap::new();
self.crc_cache.clear_poison();
e.into_inner()
});
writer.clear();
Ok(())
}
pub fn set_additional_data_paths(&mut self, additional_data_paths: Vec<PathBuf>) {