summaryrefslogtreecommitdiffstats
path: root/libimagstore
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2016-10-07 19:20:34 +0200
committerMatthias Beyer <mail@beyermatthias.de>2016-10-07 21:18:49 +0200
commit095ae194162dd58612bd772b3f842e0fe61249d1 (patch)
tree04bc8b77196695f4daa6120cd0a3232b6e06aca6 /libimagstore
parentcf50ddae3380c1736b17f3e31c529d1e8d3361b8 (diff)
[CHERRY-PICK] Add flag for _update() whether precense should be modified
This is a bugfix for an very particular issue. Here's what happens: If we create() an FileLockEntry and then update() it, we are running into a problem because update() calls _update() which changes the precense status of a FileLockEntry. Because update() is _consuming_, the FileLockEntry gets drop()ed afterwards. This _again_ causes _update() to be called, but with a new presence status, which is not true in this moment (as the FileLockEntry is still borrowed, but we already marked it as present). This patch is a short-term fix. The real problem is, that our Store interface is consuming. If the Store interface would be non-consuming, this issue wouldn't happen, as the drop() call would not happen. I'm rather sure that this patch will not be reverted in the process of rewriting the Store interface to be non-consuming. But we never know.
Diffstat (limited to 'libimagstore')
-rw-r--r--libimagstore/src/store.rs12
1 files changed, 7 insertions, 5 deletions
diff --git a/libimagstore/src/store.rs b/libimagstore/src/store.rs
index 5ce2bc6c..75ae0d37 100644
--- a/libimagstore/src/store.rs
+++ b/libimagstore/src/store.rs
@@ -507,7 +507,7 @@ impl Store {
.map_err_into(SEK::UpdateCallError);
}
- if let Err(e) = self._update(&entry) {
+ if let Err(e) = self._update(&entry, false) {
return Err(e).map_err_into(SEK::UpdateCallError);
}
@@ -522,7 +522,7 @@ impl Store {
/// # Assumptions
/// This method assumes that entry is dropped _right after_ the call, hence
/// it is not public.
- fn _update<'a>(&'a self, entry: &FileLockEntry<'a>) -> Result<()> {
+ fn _update<'a>(&'a self, entry: &FileLockEntry<'a>, modify_presence: bool) -> Result<()> {
let mut hsmap = match self.entries.write() {
Err(_) => return Err(SE::new(SEK::LockPoisoned, None)),
Ok(e) => e,
@@ -537,7 +537,9 @@ impl Store {
debug!("Writing Entry");
try!(se.write_entry(&entry.entry));
- se.status = StoreEntryStatus::Present;
+ if modify_presence {
+ se.status = StoreEntryStatus::Present;
+ }
Ok(())
}
@@ -928,7 +930,7 @@ impl<'a> DerefMut for FileLockEntry<'a> {
impl<'a> Drop for FileLockEntry<'a> {
/// This will silently ignore errors, use `Store::update` if you want to catch the errors
fn drop(&mut self) {
- let _ = self.store._update(self);
+ let _ = self.store._update(self, true);
}
}
@@ -936,7 +938,7 @@ impl<'a> Drop for FileLockEntry<'a> {
impl<'a> Drop for FileLockEntry<'a> {
/// This will not silently ignore errors but prints the result of the _update() call for testing
fn drop(&mut self) {
- println!("Drop Result: {:?}", self.store._update(self));
+ println!("Drop Result: {:?}", self.store._update(self, true));
}
}