Browse Source

lib/model: Wait for folder to stop (fixes #4981) (#4982)

Simon Frei 7 years ago
parent
commit
b7234785f8
2 changed files with 11 additions and 3 deletions
  1. 4 0
      lib/model/folder.go
  2. 7 3
      lib/model/model.go

+ 4 - 0
lib/model/folder.go

@@ -37,6 +37,7 @@ type folder struct {
 	scanNow             chan rescanRequest
 	scanDelay           chan time.Duration
 	initialScanFinished chan struct{}
+	stopped             chan struct{}
 
 	pullScheduled chan struct{}
 
@@ -81,6 +82,7 @@ func newFolder(model *Model, cfg config.FolderConfiguration) folder {
 		watchCancel: func() {},
 		watchErr:    errWatchNotStarted,
 		watchErrMut: sync.NewMutex(),
+		stopped:     make(chan struct{}),
 	}
 }
 
@@ -91,6 +93,7 @@ func (f *folder) Serve() {
 	defer func() {
 		f.scanTimer.Stop()
 		f.setState(FolderIdle)
+		close(f.stopped)
 	}()
 
 	pause := f.basePause()
@@ -223,6 +226,7 @@ func (f *folder) Delay(next time.Duration) {
 
 func (f *folder) Stop() {
 	f.cancel()
+	<-f.stopped
 }
 
 // CheckHealth checks the folder for common errors, updates the folder state

+ 7 - 3
lib/model/model.go

@@ -344,10 +344,14 @@ func (m *Model) RemoveFolder(cfg config.FolderConfiguration) {
 }
 
 func (m *Model) tearDownFolderLocked(cfg config.FolderConfiguration) {
-	// Stop the services running for this folder
-	for _, id := range m.folderRunnerTokens[cfg.ID] {
-		m.Remove(id)
+	// Stop the services running for this folder and wait for them to finish
+	// stopping to prevent races on restart.
+	tokens := m.folderRunnerTokens[cfg.ID]
+	m.fmut.Unlock()
+	for _, id := range tokens {
+		m.RemoveAndWait(id, 0)
 	}
+	m.fmut.Lock()
 
 	// Close connections to affected devices
 	for _, dev := range cfg.Devices {