diff options
| author | Michael Vogt <mvo@ubuntu.com> | 2018-08-14 11:07:46 +0200 |
|---|---|---|
| committer | Michael Vogt <mvo@ubuntu.com> | 2018-08-14 11:18:10 +0200 |
| commit | 96f8c09048b8f226771217ea329ba71cf744924e (patch) | |
| tree | 21fb11e5d61996ddee2e1c52d77f8dac5b3f2e89 | |
| parent | 385efa21c4bfbbf4f2cec62889e90e8ee2c0ad98 (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.go | 5 |
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() |
