lib/model: Fix locking order in Availability() (fixes #3634)

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3714
This commit is contained in:
Jakob Borg 2016-11-08 06:38:50 +00:00
parent 3f9b75b7b3
commit ae4cc94a9d
1 changed files with 6 additions and 3 deletions

View File

@ -2070,15 +2070,18 @@ func (m *Model) GlobalDirectoryTree(folder, prefix string, levels int, dirsonly
} }
func (m *Model) Availability(folder, file string, version protocol.Vector, block protocol.BlockInfo) []Availability { func (m *Model) Availability(folder, file string, version protocol.Vector, block protocol.BlockInfo) []Availability {
// Acquire this lock first, as the value returned from foldersFiles can // The slightly unusual locking sequence here is because we need to hold
// get heavily modified on Close() // pmut for the duration (as the value returned from foldersFiles can
// get heavily modified on Close()), but also must acquire fmut before
// pmut. (The locks can be *released* in any order.)
m.fmut.RLock()
m.pmut.RLock() m.pmut.RLock()
defer m.pmut.RUnlock() defer m.pmut.RUnlock()
m.fmut.RLock()
fs, ok := m.folderFiles[folder] fs, ok := m.folderFiles[folder]
devices := m.folderDevices[folder] devices := m.folderDevices[folder]
m.fmut.RUnlock() m.fmut.RUnlock()
if !ok { if !ok {
return nil return nil
} }