Skip to content

Commit

Permalink
lib/model: Close connections when model is stopped (syncthing#5733)
Browse files Browse the repository at this point in the history
  • Loading branch information
imsodin committed May 25, 2019
1 parent 5d35b2c commit 64518b0
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
20 changes: 20 additions & 0 deletions lib/model/model.go
Expand Up @@ -180,6 +180,7 @@ var (
// errors about why a connection is closed
errIgnoredFolderRemoved = errors.New("folder no longer ignored")
errReplacingConnection = errors.New("replacing connection")
errStopped = errors.New("Syncthing is being stopped")
)

// NewModel creates and starts a new model. The model starts in read-only mode,
Expand Down Expand Up @@ -225,6 +226,25 @@ func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersio
return m
}

func (m *model) Stop() {
m.Supervisor.Stop()
devs := m.cfg.Devices()
ids := make([]protocol.DeviceID, 0, len(devs))
for id := range devs {
ids = append(ids, id)
}
m.pmut.RLock()
closed := make([]chan struct{}, 0, len(m.closed))
for _, c := range m.closed {
closed = append(closed, c)
}
m.pmut.RUnlock()
m.closeConns(ids, errStopped)
for _, c := range closed {
<-c
}
}

// StartDeadlockDetector starts a deadlock detector on the models locks which
// causes panics in case the locks cannot be acquired in the given timeout
// period.
Expand Down
17 changes: 2 additions & 15 deletions lib/model/model_test.go
Expand Up @@ -862,15 +862,6 @@ func TestIssue5063(t *testing.T) {
m := newState(defaultAutoAcceptCfg)
defer cleanupModel(m)

m.pmut.Lock()
for _, c := range m.conn {
conn := c.(*fakeConnection)
conn.mut.Lock()
conn.closeFn = func(_ error) {}
conn.mut.Unlock()
}
m.pmut.Unlock()

wg := sync.WaitGroup{}

addAndVerify := func(id string) {
Expand Down Expand Up @@ -3267,12 +3258,7 @@ func TestSanitizePath(t *testing.T) {
func TestConnCloseOnRestart(t *testing.T) {
w, fcfg := tmpDefaultWrapper()
m := setupModel(w)
defer func() {
m.Stop()
m.db.Close()
os.RemoveAll(fcfg.Filesystem().URI())
os.Remove(w.ConfigPath())
}()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI())

br := &testutils.BlockingRW{}
nw := &testutils.NoopRW{}
Expand All @@ -3291,6 +3277,7 @@ func TestConnCloseOnRestart(t *testing.T) {
t.Fatal("Timed out before folder restart returned")
}
m.pmut.RLock()
defer m.pmut.RUnlock()
if len(m.conn) != 0 {
t.Errorf("Conn wasn't removed on restart (len(m.conn) == %v)", len(m.conn))
}
Expand Down

0 comments on commit 64518b0

Please sign in to comment.