2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-05 04:47:51 +00:00

Lock MasterIndex and InFlight store together

fixes: #358
This commit is contained in:
Philipp Serr 2015-12-28 18:18:25 +01:00
parent e7bf936d2b
commit 0fde09a866

View File

@ -157,13 +157,23 @@ func (mi *MasterIndex) Current() *Index {
// AddInFlight add the given ID to the list of in-flight IDs. An error is // AddInFlight add the given ID to the list of in-flight IDs. An error is
// returned when the ID is already in the list. // returned when the ID is already in the list.
func (mi *MasterIndex) AddInFlight(id backend.ID) error { func (mi *MasterIndex) AddInFlight(id backend.ID) error {
// The index + inFlight store must be searched for a matching id in one
// atomic operation. This requires locking the inFlight store and the
// index together!
mi.inFlight.Lock() mi.inFlight.Lock()
defer mi.inFlight.Unlock() defer mi.inFlight.Unlock()
// Note: mi.Has read locks the index again.
mi.idxMutex.RLock()
defer mi.idxMutex.RUnlock()
debug.Log("MasterIndex.AddInFlight", "adding %v", id) debug.Log("MasterIndex.AddInFlight", "adding %v", id)
if mi.inFlight.Has(id) { if mi.inFlight.Has(id) {
return fmt.Errorf("%v is already in flight", id) return fmt.Errorf("%v is already in flight", id)
} }
if mi.Has(id) {
return fmt.Errorf("%v is already indexed (fully processed)", id)
}
mi.inFlight.Insert(id) mi.inFlight.Insert(id)
return nil return nil
@ -171,12 +181,22 @@ func (mi *MasterIndex) AddInFlight(id backend.ID) error {
// IsInFlight returns true iff the id is contained in the list of in-flight IDs. // IsInFlight returns true iff the id is contained in the list of in-flight IDs.
func (mi *MasterIndex) IsInFlight(id backend.ID) bool { func (mi *MasterIndex) IsInFlight(id backend.ID) bool {
// The index + inFlight store must be searched for a matching id in one
// atomic operation. This requires locking the inFlight store and the
// index together!
mi.inFlight.RLock() mi.inFlight.RLock()
defer mi.inFlight.RUnlock() defer mi.inFlight.RUnlock()
// Note: mi.Has read locks the index again.
mi.idxMutex.RLock()
defer mi.idxMutex.RUnlock()
inFlight := mi.inFlight.Has(id) inFlight := mi.inFlight.Has(id)
debug.Log("MasterIndex.IsInFlight", "testing whether %v is in flight: %v", id.Str(), inFlight) debug.Log("MasterIndex.IsInFlight", "testing whether %v is in flight: %v", id.Str(), inFlight)
indexed := mi.Has(id)
debug.Log("MasterIndex.IsInFlight", "testing whether %v is indexed (fully processed): %v", id.Str(), indexed)
return inFlight return inFlight
} }