Merge pull request #582 from ethcore/secret-store-sync-ready
making key directory thread-safe
This commit is contained in:
commit
9c1f3d5fff
@ -461,17 +461,17 @@ enum KeyFileLoadError {
|
||||
pub struct KeyDirectory {
|
||||
/// Directory path for key management.
|
||||
path: String,
|
||||
cache: RefCell<HashMap<Uuid, KeyFileContent>>,
|
||||
cache_usage: RefCell<VecDeque<Uuid>>,
|
||||
cache: RwLock<HashMap<Uuid, KeyFileContent>>,
|
||||
cache_usage: RwLock<VecDeque<Uuid>>,
|
||||
}
|
||||
|
||||
impl KeyDirectory {
|
||||
/// Initializes new cache directory context with a given `path`
|
||||
pub fn new(path: &Path) -> KeyDirectory {
|
||||
KeyDirectory {
|
||||
cache: RefCell::new(HashMap::new()),
|
||||
cache: RwLock::new(HashMap::new()),
|
||||
path: path.to_str().expect("Initialized key directory with empty path").to_owned(),
|
||||
cache_usage: RefCell::new(VecDeque::new()),
|
||||
cache_usage: RwLock::new(VecDeque::new()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -484,7 +484,7 @@ impl KeyDirectory {
|
||||
let json_bytes = json_text.into_bytes();
|
||||
try!(file.write(&json_bytes));
|
||||
}
|
||||
let mut cache = self.cache.borrow_mut();
|
||||
let mut cache = self.cache.write().unwrap();
|
||||
let id = key_file.id.clone();
|
||||
cache.insert(id.clone(), key_file);
|
||||
Ok(id.clone())
|
||||
@ -495,14 +495,14 @@ impl KeyDirectory {
|
||||
pub fn get(&self, id: &Uuid) -> Option<KeyFileContent> {
|
||||
let path = self.key_path(id);
|
||||
{
|
||||
let mut usage = self.cache_usage.borrow_mut();
|
||||
let mut usage = self.cache_usage.write().unwrap();
|
||||
usage.push_back(id.clone());
|
||||
}
|
||||
|
||||
if !self.cache.borrow().contains_key(id) {
|
||||
if !self.cache.read().unwrap().contains_key(id) {
|
||||
match KeyDirectory::load_key(&path) {
|
||||
Ok(loaded_key) => {
|
||||
self.cache.borrow_mut().insert(id.to_owned(), loaded_key);
|
||||
self.cache.write().unwrap().insert(id.to_owned(), loaded_key);
|
||||
}
|
||||
Err(error) => {
|
||||
warn!(target: "sstore", "error loading key {:?}: {:?}", id, error);
|
||||
@ -512,7 +512,7 @@ impl KeyDirectory {
|
||||
}
|
||||
|
||||
// todo: replace with Ref::map when it stabilized to avoid copies
|
||||
Some(self.cache.borrow().get(id)
|
||||
Some(self.cache.read().unwrap().get(id)
|
||||
.expect("Key should be there, we have just inserted or checked it.")
|
||||
.clone())
|
||||
}
|
||||
@ -524,7 +524,7 @@ impl KeyDirectory {
|
||||
|
||||
/// Removes keys that never been requested during last `MAX_USAGE_TRACK` times
|
||||
pub fn collect_garbage(&mut self) {
|
||||
let mut cache_usage = self.cache_usage.borrow_mut();
|
||||
let mut cache_usage = self.cache_usage.write().unwrap();
|
||||
|
||||
let total_usages = cache_usage.len();
|
||||
let untracked_usages = max(total_usages as i64 - MAX_CACHE_USAGE_TRACK as i64, 0) as usize;
|
||||
@ -532,31 +532,31 @@ impl KeyDirectory {
|
||||
cache_usage.drain(..untracked_usages);
|
||||
}
|
||||
|
||||
if self.cache.borrow().len() <= MAX_CACHE_USAGE_TRACK { return; }
|
||||
if self.cache.read().unwrap().len() <= MAX_CACHE_USAGE_TRACK { return; }
|
||||
|
||||
let uniqs: HashSet<&Uuid> = cache_usage.iter().collect();
|
||||
let removes:Vec<Uuid> = {
|
||||
let cache = self.cache.borrow();
|
||||
let cache = self.cache.read().unwrap();
|
||||
cache.keys().cloned().filter(|key| !uniqs.contains(key)).collect()
|
||||
};
|
||||
if removes.is_empty() { return; }
|
||||
let mut cache = self.cache.borrow_mut();
|
||||
let mut cache = self.cache.write().unwrap();
|
||||
for key in removes { cache.remove(&key); }
|
||||
}
|
||||
|
||||
/// Reports how many keys are currently cached.
|
||||
pub fn cache_size(&self) -> usize {
|
||||
self.cache.borrow().len()
|
||||
self.cache.read().unwrap().len()
|
||||
}
|
||||
|
||||
/// Removes key file from key directory
|
||||
pub fn delete(&mut self, id: &Uuid) -> Result<(), ::std::io::Error> {
|
||||
let path = self.key_path(id);
|
||||
|
||||
if !self.cache.borrow().contains_key(id) {
|
||||
if !self.cache.read().unwrap().contains_key(id) {
|
||||
return match fs::remove_file(&path) {
|
||||
Ok(_) => {
|
||||
self.cache.borrow_mut().remove(&id);
|
||||
self.cache.write().unwrap().remove(&id);
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => Err(e)
|
||||
|
Loading…
Reference in New Issue
Block a user