diff --git a/server/configuration.go b/server/configuration.go index 3cf39b4..11ac4bb 100644 --- a/server/configuration.go +++ b/server/configuration.go @@ -77,6 +77,13 @@ func (s *Server) Config() *Configuration { return &s.cfg } +func (c *Configuration) GetUuid() string { + c.mu.RLock() + defer c.mu.RUnlock() + + return c.Uuid +} + func (c *Configuration) SetSuspended(s bool) { c.mu.Lock() c.Suspended = s diff --git a/server/resources.go b/server/resources.go index 5ded93c..f333cb8 100644 --- a/server/resources.go +++ b/server/resources.go @@ -54,6 +54,15 @@ func (s *Server) Proc() *ResourceUsage { return &s.resources } +// Returns the servers current state. +func (ru *ResourceUsage) getInternalState() string { + ru.mu.RLock() + defer ru.mu.RUnlock() + + return ru.State +} + +// Sets the new state for the server. func (ru *ResourceUsage) setInternalState(state string) { ru.mu.Lock() ru.State = state diff --git a/server/server.go b/server/server.go index df0ae60..6e10f1a 100644 --- a/server/server.go +++ b/server/server.go @@ -68,7 +68,7 @@ type InstallerDetails struct { // Returns the UUID for the server instance. func (s *Server) Id() string { - return s.Config().Uuid + return s.Config().GetUuid() } // Returns all of the environment variables that should be assigned to a running diff --git a/server/state.go b/server/state.go index 705d524..5ff4ab9 100644 --- a/server/state.go +++ b/server/state.go @@ -126,7 +126,7 @@ func (s *Server) SetState(state string) error { // Returns the current state of the server in a race-safe manner. func (s *Server) GetState() string { - return s.Proc().State + return s.Proc().getInternalState() } // Determines if the server state is running or not. This is different than the diff --git a/server/update.go b/server/update.go index 750da12..5d9a211 100644 --- a/server/update.go +++ b/server/update.go @@ -28,7 +28,14 @@ func (s *Server) UpdateDataStructure(data []byte, background bool) error { } // Grab a copy of the configuration to work on. - c := s.Config() + c := *s.Config() + + // Lock our copy of the configuration since the defered unlock will end up acting upon this + // new memory address rather than the old one. If we don't lock this, the defered unlock will + // cause a panic when it goes to run. However, since we only update s.cfg at the end, if there + // is an error before that point we'll still properly unlock the original configuration for the + // server. + c.mu.Lock() // Lock the server configuration while we're doing this merge to avoid anything // trying to overwrite it or make modifications while we're sorting out what we @@ -38,7 +45,7 @@ func (s *Server) UpdateDataStructure(data []byte, background bool) error { // Merge the new data object that we have received with the existing server data object // and then save it to the disk so it is persistent. - if err := mergo.Merge(c, src, mergo.WithOverride); err != nil { + if err := mergo.Merge(&c, src, mergo.WithOverride); err != nil { return errors.WithStack(err) } @@ -87,7 +94,7 @@ func (s *Server) UpdateDataStructure(data []byte, background bool) error { } // Update the configuration once we have a lock on the configuration object. - s.cfg = *c + s.cfg = c s.Uuid = c.Uuid if background {