Address some race conditions

This commit is contained in:
Dane Everitt 2020-07-19 17:46:39 -07:00
parent 21e58b57a1
commit e28c05ae56
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
5 changed files with 28 additions and 5 deletions

View File

@ -77,6 +77,13 @@ func (s *Server) Config() *Configuration {
return &s.cfg return &s.cfg
} }
func (c *Configuration) GetUuid() string {
c.mu.RLock()
defer c.mu.RUnlock()
return c.Uuid
}
func (c *Configuration) SetSuspended(s bool) { func (c *Configuration) SetSuspended(s bool) {
c.mu.Lock() c.mu.Lock()
c.Suspended = s c.Suspended = s

View File

@ -54,6 +54,15 @@ func (s *Server) Proc() *ResourceUsage {
return &s.resources 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) { func (ru *ResourceUsage) setInternalState(state string) {
ru.mu.Lock() ru.mu.Lock()
ru.State = state ru.State = state

View File

@ -68,7 +68,7 @@ type InstallerDetails struct {
// Returns the UUID for the server instance. // Returns the UUID for the server instance.
func (s *Server) Id() string { 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 // Returns all of the environment variables that should be assigned to a running

View File

@ -126,7 +126,7 @@ func (s *Server) SetState(state string) error {
// Returns the current state of the server in a race-safe manner. // Returns the current state of the server in a race-safe manner.
func (s *Server) GetState() string { 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 // Determines if the server state is running or not. This is different than the

View File

@ -28,7 +28,14 @@ func (s *Server) UpdateDataStructure(data []byte, background bool) error {
} }
// Grab a copy of the configuration to work on. // 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 // 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 // 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 // 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. // 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) 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. // Update the configuration once we have a lock on the configuration object.
s.cfg = *c s.cfg = c
s.Uuid = c.Uuid s.Uuid = c.Uuid
if background { if background {