mirror of
https://github.com/loot/loot-condition-interpreter.git
synced 2026-07-27 14:16:09 -07:00
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:
+16
-7
@@ -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
@@ -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>) {
|
||||
|
||||
Reference in New Issue
Block a user