summaryrefslogtreecommitdiff
diff options
authorMichael Vogt <mvo@ubuntu.com>2018-08-14 11:07:46 +0200
committerMichael Vogt <mvo@ubuntu.com>2018-08-14 11:18:10 +0200
commit96f8c09048b8f226771217ea329ba71cf744924e (patch)
tree21fb11e5d61996ddee2e1c52d77f8dac5b3f2e89
parent385efa21c4bfbbf4f2cec62889e90e8ee2c0ad98 (diff)
hookstate: fix deadlock in TestHookTaskCanKillHook testfix-armhf-hang
The TestHookTaskCanKillHook test will do something like: 1. create change 2. setup go-routine that will calll StateEngine.Wait() 3. abort the created change 4. run StateEngine.Ensure() Both (2) and (4) will grab the StateEngine.mgrLock - but if it is taken in (2) it will never be released because there in StateEngine.Wait() it will loop over the managers and call wait on each which includes the StateEngine which notices that one task is in abort state and
-rw-r--r--overlord/hookstate/hookstate_test.go5
1 files changed, 5 insertions, 0 deletions
diff --git a/overlord/hookstate/hookstate_test.go b/overlord/hookstate/hookstate_test.go
index 1f4277e4c2..ac86e068fe 100644
--- a/overlord/hookstate/hookstate_test.go
+++ b/overlord/hookstate/hookstate_test.go
@@ -525,8 +525,12 @@ func (s *hookManagerSuite) TestHookTaskCanKillHook(c *C) {
defer cmd.Restore()
s.se.Ensure()
+ readyForWait := make(chan struct{})
completed := make(chan struct{})
go func() {
+ <-readyForWait
+ // wait will take the se.mgrLock so when it runs in parallel
+ // with Ensure it dead-locks
s.se.Wait()
close(completed)
}()
@@ -537,6 +541,7 @@ func (s *hookManagerSuite) TestHookTaskCanKillHook(c *C) {
s.change.Abort()
s.state.Unlock()
s.se.Ensure()
+ close(readyForWait)
<-completed
s.state.Lock()