lib/model: Consistent use of locks (#5684)

This commit is contained in:
Simon Frei 2019-05-02 19:55:39 +02:00 committed by Audrius Butkevicius
parent 5954b105cd
commit 5fa8467756

View File

@ -363,8 +363,8 @@ func (m *model) AddFolder(cfg config.FolderConfiguration) {
} }
m.fmut.Lock() m.fmut.Lock()
defer m.fmut.Unlock()
m.addFolderLocked(cfg) m.addFolderLocked(cfg)
m.fmut.Unlock()
} }
func (m *model) addFolderLocked(cfg config.FolderConfiguration) { func (m *model) addFolderLocked(cfg config.FolderConfiguration) {
@ -585,6 +585,8 @@ func (info ConnectionInfo) MarshalJSON() ([]byte, error) {
func (m *model) ConnectionStats() map[string]interface{} { func (m *model) ConnectionStats() map[string]interface{} {
m.fmut.RLock() m.fmut.RLock()
m.pmut.RLock() m.pmut.RLock()
defer m.pmut.RUnlock()
defer m.fmut.RUnlock()
res := make(map[string]interface{}) res := make(map[string]interface{})
devs := m.cfg.Devices() devs := m.cfg.Devices()
@ -614,9 +616,6 @@ func (m *model) ConnectionStats() map[string]interface{} {
res["connections"] = conns res["connections"] = conns
m.pmut.RUnlock()
m.fmut.RUnlock()
in, out := protocol.TotalInOut() in, out := protocol.TotalInOut()
res["total"] = ConnectionInfo{ res["total"] = ConnectionInfo{
Statistics: protocol.Statistics{ Statistics: protocol.Statistics{
@ -787,11 +786,12 @@ func (m *model) ReceiveOnlyChangedSize(folder string) db.Counts {
// NeedSize returns the number and total size of currently needed files. // NeedSize returns the number and total size of currently needed files.
func (m *model) NeedSize(folder string) db.Counts { func (m *model) NeedSize(folder string) db.Counts {
m.fmut.RLock() m.fmut.RLock()
defer m.fmut.RUnlock() rf, ok := m.folderFiles[folder]
cfg := m.folderCfgs[folder]
m.fmut.RUnlock()
var result db.Counts var result db.Counts
if rf, ok := m.folderFiles[folder]; ok { if ok {
cfg := m.folderCfgs[folder]
rf.WithNeedTruncated(protocol.LocalDeviceID, func(f db.FileIntf) bool { rf.WithNeedTruncated(protocol.LocalDeviceID, func(f db.FileIntf) bool {
if cfg.IgnoreDelete && f.IsDeleted() { if cfg.IgnoreDelete && f.IsDeleted() {
return true return true
@ -811,10 +811,12 @@ func (m *model) NeedSize(folder string) db.Counts {
// total number of files currently needed. // total number of files currently needed.
func (m *model) NeedFolderFiles(folder string, page, perpage int) ([]db.FileInfoTruncated, []db.FileInfoTruncated, []db.FileInfoTruncated) { func (m *model) NeedFolderFiles(folder string, page, perpage int) ([]db.FileInfoTruncated, []db.FileInfoTruncated, []db.FileInfoTruncated) {
m.fmut.RLock() m.fmut.RLock()
defer m.fmut.RUnlock() rf, rfOk := m.folderFiles[folder]
runner, runnerOk := m.folderRunners[folder]
cfg := m.folderCfgs[folder]
m.fmut.RUnlock()
rf, ok := m.folderFiles[folder] if !rfOk {
if !ok {
return nil, nil, nil return nil, nil, nil
} }
@ -824,8 +826,7 @@ func (m *model) NeedFolderFiles(folder string, page, perpage int) ([]db.FileInfo
skip := (page - 1) * perpage skip := (page - 1) * perpage
get := perpage get := perpage
runner, ok := m.folderRunners[folder] if runnerOk {
if ok {
allProgressNames, allQueuedNames := runner.Jobs() allProgressNames, allQueuedNames := runner.Jobs()
var progressNames, queuedNames []string var progressNames, queuedNames []string
@ -852,7 +853,6 @@ func (m *model) NeedFolderFiles(folder string, page, perpage int) ([]db.FileInfo
} }
rest = make([]db.FileInfoTruncated, 0, perpage) rest = make([]db.FileInfoTruncated, 0, perpage)
cfg := m.folderCfgs[folder]
rf.WithNeedTruncated(protocol.LocalDeviceID, func(f db.FileIntf) bool { rf.WithNeedTruncated(protocol.LocalDeviceID, func(f db.FileIntf) bool {
if cfg.IgnoreDelete && f.IsDeleted() { if cfg.IgnoreDelete && f.IsDeleted() {
return true return true
@ -878,13 +878,13 @@ func (m *model) NeedFolderFiles(folder string, page, perpage int) ([]db.FileInfo
// total number of files currently needed. // total number of files currently needed.
func (m *model) LocalChangedFiles(folder string, page, perpage int) []db.FileInfoTruncated { func (m *model) LocalChangedFiles(folder string, page, perpage int) []db.FileInfoTruncated {
m.fmut.RLock() m.fmut.RLock()
defer m.fmut.RUnlock()
rf, ok := m.folderFiles[folder] rf, ok := m.folderFiles[folder]
fcfg := m.folderCfgs[folder]
m.fmut.RUnlock()
if !ok { if !ok {
return nil return nil
} }
fcfg := m.folderCfgs[folder]
if fcfg.Type != config.FolderTypeReceiveOnly { if fcfg.Type != config.FolderTypeReceiveOnly {
return nil return nil
} }
@ -1046,6 +1046,7 @@ func (m *model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
} }
m.fmut.Lock() m.fmut.Lock()
defer m.fmut.Unlock()
var paused []string var paused []string
for _, folder := range cm.Folders { for _, folder := range cm.Folders {
cfg, ok := m.cfg.Folder(folder.ID) cfg, ok := m.cfg.Folder(folder.ID)
@ -1181,7 +1182,6 @@ func (m *model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
changed = true changed = true
} }
} }
m.fmut.Unlock()
if changed { if changed {
if err := m.cfg.Save(); err != nil { if err := m.cfg.Save(); err != nil {
@ -1653,12 +1653,13 @@ func (m *model) Connection(deviceID protocol.DeviceID) (connections.Connection,
func (m *model) GetIgnores(folder string) ([]string, []string, error) { func (m *model) GetIgnores(folder string) ([]string, []string, error) {
m.fmut.RLock() m.fmut.RLock()
defer m.fmut.RUnlock() cfg, cfgOk := m.folderCfgs[folder]
ignores, ignoresOk := m.folderIgnores[folder]
m.fmut.RUnlock()
cfg, ok := m.folderCfgs[folder] if !cfgOk {
if !ok { cfg, cfgOk = m.cfg.Folders()[folder]
cfg, ok = m.cfg.Folders()[folder] if !cfgOk {
if !ok {
return nil, nil, fmt.Errorf("Folder %s does not exist", folder) return nil, nil, fmt.Errorf("Folder %s does not exist", folder)
} }
} }
@ -1668,8 +1669,7 @@ func (m *model) GetIgnores(folder string) ([]string, []string, error) {
return nil, nil, err return nil, nil, err
} }
ignores, ok := m.folderIgnores[folder] if !ignoresOk {
if !ok {
ignores = ignore.New(fs.NewFilesystem(cfg.FilesystemType, cfg.Path)) ignores = ignore.New(fs.NewFilesystem(cfg.FilesystemType, cfg.Path))
} }
@ -2032,13 +2032,14 @@ func (m *model) ScanFolder(folder string) error {
func (m *model) ScanFolderSubdirs(folder string, subs []string) error { func (m *model) ScanFolderSubdirs(folder string, subs []string) error {
m.fmut.RLock() m.fmut.RLock()
if err := m.checkFolderRunningLocked(folder); err != nil { err := m.checkFolderRunningLocked(folder)
m.fmut.RUnlock()
return err
}
runner := m.folderRunners[folder] runner := m.folderRunners[folder]
m.fmut.RUnlock() m.fmut.RUnlock()
if err != nil {
return err
}
return runner.Scan(subs) return runner.Scan(subs)
} }
@ -2223,10 +2224,10 @@ func (m *model) CurrentSequence(folder string) (int64, bool) {
// the remote or global folder has changed. // the remote or global folder has changed.
func (m *model) RemoteSequence(folder string) (int64, bool) { func (m *model) RemoteSequence(folder string) (int64, bool) {
m.fmut.RLock() m.fmut.RLock()
defer m.fmut.RUnlock()
fs, ok := m.folderFiles[folder] fs, ok := m.folderFiles[folder]
cfg := m.folderCfgs[folder] cfg := m.folderCfgs[folder]
m.fmut.RUnlock()
if !ok { if !ok {
// The folder might not exist, since this can be called with a user // The folder might not exist, since this can be called with a user
// specified folder name from the REST interface. // specified folder name from the REST interface.
@ -2386,8 +2387,9 @@ next:
// BringToFront bumps the given files priority in the job queue. // BringToFront bumps the given files priority in the job queue.
func (m *model) BringToFront(folder, file string) { func (m *model) BringToFront(folder, file string) {
m.fmut.RLock() m.fmut.RLock()
defer m.fmut.RUnlock()
runner, ok := m.folderRunners[folder] runner, ok := m.folderRunners[folder]
m.fmut.RUnlock()
if ok { if ok {
runner.BringToFront(file) runner.BringToFront(file)
} }