diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index e58c909a0..762ff7551 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -99,7 +99,7 @@ type modelIntf interface { type configIntf interface { GUI() config.GUIConfiguration - Raw() config.Configuration + RawCopy() config.Configuration Options() config.OptionsConfiguration Replace(cfg config.Configuration) error Subscribe(c config.Committer) @@ -736,7 +736,7 @@ func (s *apiService) getDBFile(w http.ResponseWriter, r *http.Request) { } func (s *apiService) getSystemConfig(w http.ResponseWriter, r *http.Request) { - sendJSON(w, s.cfg.Raw()) + sendJSON(w, s.cfg.RawCopy()) } func (s *apiService) postSystemConfig(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index e0d9d5531..efee5101b 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -672,7 +672,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) { } } - if cfg.Raw().OriginalVersion == 15 { + if cfg.RawCopy().OriginalVersion == 15 { // The config version 15->16 migration is about handling ignores and // delta indexes and requires that we drop existing indexes that // have been incorrectly ignore filtered. @@ -871,7 +871,7 @@ func loadOrCreateConfig() *config.Wrapper { l.Fatalln("Config:", err) } - if cfg.Raw().OriginalVersion != config.CurrentVersion { + if cfg.RawCopy().OriginalVersion != config.CurrentVersion { err = archiveAndSaveConfig(cfg) if err != nil { l.Fatalln("Config archive:", err) @@ -883,7 +883,7 @@ func loadOrCreateConfig() *config.Wrapper { func archiveAndSaveConfig(cfg *config.Wrapper) error { // Copy the existing config to an archive copy - archivePath := cfg.ConfigPath() + fmt.Sprintf(".v%d", cfg.Raw().OriginalVersion) + archivePath := cfg.ConfigPath() + fmt.Sprintf(".v%d", cfg.RawCopy().OriginalVersion) l.Infoln("Archiving a copy of old config file format at:", archivePath) if err := copyFile(cfg.ConfigPath(), archivePath); err != nil { return err diff --git a/cmd/syncthing/mocked_config_test.go b/cmd/syncthing/mocked_config_test.go index 55686f51f..ed320d0a7 100644 --- a/cmd/syncthing/mocked_config_test.go +++ b/cmd/syncthing/mocked_config_test.go @@ -23,7 +23,7 @@ func (c *mockedConfig) ListenAddresses() []string { return nil } -func (c *mockedConfig) Raw() config.Configuration { +func (c *mockedConfig) RawCopy() config.Configuration { return config.Configuration{} } diff --git a/cmd/syncthing/usage_report.go b/cmd/syncthing/usage_report.go index b72cad633..ceaf69464 100644 --- a/cmd/syncthing/usage_report.go +++ b/cmd/syncthing/usage_report.go @@ -45,7 +45,7 @@ func newUsageReportingManager(cfg *config.Wrapper, m *model.Model) *usageReporti } // Start UR if it's enabled. - mgr.CommitConfiguration(config.Configuration{}, cfg.Raw()) + mgr.CommitConfiguration(config.Configuration{}, cfg.RawCopy()) // Listen to future config changes so that we can start and stop as // appropriate. diff --git a/lib/config/commit_test.go b/lib/config/commit_test.go index bc58b47b8..641418e08 100644 --- a/lib/config/commit_test.go +++ b/lib/config/commit_test.go @@ -43,7 +43,7 @@ func (validationError) String() string { func TestReplaceCommit(t *testing.T) { w := Wrap("/dev/null", Configuration{Version: 0}) - if w.Raw().Version != 0 { + if w.RawCopy().Version != 0 { t.Fatal("Config incorrect") } @@ -57,7 +57,7 @@ func TestReplaceCommit(t *testing.T) { if w.RequiresRestart() { t.Fatal("Should not require restart") } - if w.Raw().Version != CurrentVersion { + if w.RawCopy().Version != CurrentVersion { t.Fatal("Config should have changed") } @@ -76,7 +76,7 @@ func TestReplaceCommit(t *testing.T) { if !w.RequiresRestart() { t.Fatal("Should require restart") } - if w.Raw().Version != CurrentVersion { + if w.RawCopy().Version != CurrentVersion { t.Fatal("Config should have changed") } @@ -92,7 +92,7 @@ func TestReplaceCommit(t *testing.T) { if !w.RequiresRestart() { t.Fatal("Should still require restart") } - if w.Raw().Version != CurrentVersion { + if w.RawCopy().Version != CurrentVersion { t.Fatal("Config should not have changed") } } diff --git a/lib/config/config_test.go b/lib/config/config_test.go index c3cca9889..1e8767628 100644 --- a/lib/config/config_test.go +++ b/lib/config/config_test.go @@ -456,7 +456,7 @@ func TestNewSaveLoad(t *testing.T) { t.Error(err) } - if diff, equal := messagediff.PrettyDiff(cfg.Raw(), cfg2.Raw()); !equal { + if diff, equal := messagediff.PrettyDiff(cfg.RawCopy(), cfg2.RawCopy()); !equal { t.Errorf("Configs are not equal. Diff:\n%s", diff) } @@ -482,7 +482,7 @@ func TestCopy(t *testing.T) { if err != nil { t.Fatal(err) } - cfg := wrapper.Raw() + cfg := wrapper.RawCopy() bsOrig, err := json.MarshalIndent(cfg, "", " ") if err != nil { @@ -548,7 +548,7 @@ func TestPullOrder(t *testing.T) { // Serialize and deserialize again to verify it survives the transformation buf := new(bytes.Buffer) - cfg := wrapper.Raw() + cfg := wrapper.RawCopy() cfg.WriteXML(buf) t.Logf("%s", buf.Bytes()) @@ -611,7 +611,7 @@ func TestDuplicateDevices(t *testing.T) { t.Fatal(err) } - if l := len(wrapper.Raw().Devices); l != 3 { + if l := len(wrapper.RawCopy().Devices); l != 3 { t.Errorf("Incorrect number of devices, %d != 3", l) } @@ -755,7 +755,7 @@ func TestSharesRemovedOnDeviceRemoval(t *testing.T) { t.Errorf("Failed: %s", err) } - raw := wrapper.Raw() + raw := wrapper.RawCopy() raw.Devices = raw.Devices[:len(raw.Devices)-1] if len(raw.Folders[0].Devices) <= len(raw.Devices) { @@ -767,7 +767,7 @@ func TestSharesRemovedOnDeviceRemoval(t *testing.T) { t.Errorf("Failed: %s", err) } - raw = wrapper.Raw() + raw = wrapper.RawCopy() if len(raw.Folders[0].Devices) > len(raw.Devices) { t.Error("Unexpected extra device") } diff --git a/lib/config/wrapper.go b/lib/config/wrapper.go index b387b2314..894169f10 100644 --- a/lib/config/wrapper.go +++ b/lib/config/wrapper.go @@ -120,9 +120,11 @@ func (w *Wrapper) Unsubscribe(c Committer) { w.mut.Unlock() } -// Raw returns the currently wrapped Configuration object. -func (w *Wrapper) Raw() Configuration { - return w.cfg +// RawCopy returns a copy of the currently wrapped Configuration object. +func (w *Wrapper) RawCopy() Configuration { + w.mut.Lock() + defer w.mut.Unlock() + return w.cfg.Copy() } // Replace swaps the current configuration object for the given one. diff --git a/lib/connections/service.go b/lib/connections/service.go index 96caf949f..ef23f295e 100644 --- a/lib/connections/service.go +++ b/lib/connections/service.go @@ -112,7 +112,7 @@ func NewService(cfg *config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg * service.Add(serviceFunc(service.connect)) service.Add(serviceFunc(service.handle)) - raw := cfg.Raw() + raw := cfg.RawCopy() // Actually starts the listeners and NAT service service.CommitConfiguration(raw, raw) @@ -276,7 +276,7 @@ func (s *Service) connect() { var sleep time.Duration for { - cfg := s.cfg.Raw() + cfg := s.cfg.RawCopy() bestDialerPrio := 1<<31 - 1 // worse prio won't build on 32 bit for _, df := range dialers { diff --git a/lib/model/model.go b/lib/model/model.go index 51205ccae..ffa900d0d 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -970,7 +970,7 @@ func (m *Model) handleDeintroductions(introducerCfg config.DeviceConfiguration, // Check if we should remove some devices, if the introducer no longer shares any folder with them. // Yet do not remove if we share other folders that haven't been introduced by the introducer. - raw := m.cfg.Raw() + raw := m.cfg.RawCopy() deviceChanged := false for i := 0; i < len(raw.Devices); i++ { if raw.Devices[i].IntroducedBy == introducerCfg.DeviceID { diff --git a/lib/model/progressemitter.go b/lib/model/progressemitter.go index 9c35b0af8..a487f0781 100755 --- a/lib/model/progressemitter.go +++ b/lib/model/progressemitter.go @@ -42,7 +42,7 @@ func NewProgressEmitter(cfg *config.Wrapper) *ProgressEmitter { mut: sync.NewMutex(), } - t.CommitConfiguration(config.Configuration{}, cfg.Raw()) + t.CommitConfiguration(config.Configuration{}, cfg.RawCopy()) cfg.Subscribe(t) return t