From b3b62429a7bbeb852f9b26299732b265d9d3299f Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Tue, 2 Oct 2018 14:55:43 -0700 Subject: [PATCH] state/remote: Don't hang in PersistState We were calling from PersistState into RefreshState, but RefreshState is protected by the same lock as PersistState and so the call would deadlock. Instead, we introduce a new entry point refreshState which can be used when already holding the lock. --- state/remote/state.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/state/remote/state.go b/state/remote/state.go index 443b4b8214..9c0a7357a8 100644 --- a/state/remote/state.go +++ b/state/remote/state.go @@ -55,7 +55,13 @@ func (s *State) WriteState(state *states.State) error { func (s *State) RefreshState() error { s.mu.Lock() defer s.mu.Unlock() + return s.refreshState() +} +// refreshState is the main implementation of RefreshState, but split out so +// that we can make internal calls to it from methods that are already holding +// the s.mu lock. +func (s *State) refreshState() error { payload, err := s.Client.Get() if err != nil { return err @@ -95,7 +101,7 @@ func (s *State) PersistState() error { // We might be writing a new state altogether, but before we do that // we'll check to make sure there isn't already a snapshot present // that we ought to be updating. - err := s.RefreshState() + err := s.refreshState() if err != nil { return fmt.Errorf("failed checking for existing remote state: %s", err) }