Skip to content

Commit 6cb5a22

Browse files
🐛 subprocess Make sure that cancellation can't enter deadlock (#681)
<!-- Copyright (C) 2020-2022 Arm Limited or its affiliates and Contributors. All rights reserved. SPDX-License-Identifier: Apache-2.0 --> ### Description <!-- Please add any detail or context that would be useful to a reviewer. --> Make sure that cancellation can't enter deadlock ### Test Coverage <!-- Please put an `x` in the correct box e.g. `[x]` to indicate the testing coverage of this change. --> - [x] This change is covered by existing or additional automated tests. - [ ] Manual testing has been performed (and evidence provided) as automated testing was not feasible. - [ ] Additional tests are not required for this change (e.g. documentation update).
1 parent 1df09f8 commit 6cb5a22

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

changes/20250818160732.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:bug: `subprocess` Make sure that cancellation can't enter deadlock

utils/subprocess/monitoring.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,16 @@ func newSubprocessMonitoring(parentCtx context.Context) *subprocessMonitoring {
3434

3535
// CancelSubprocess interrupts an on-going process.
3636
func (s *subprocessMonitoring) CancelSubprocess() {
37-
s.monitoringStopping.Store(true)
37+
// Ensure we only ever run the cancel-store once and prevent the following deadlocks:
38+
// 1. Some functions like Execute() do defer s.Cancel()
39+
// 2. This calls subprocessMonitoring.CancelSubprocess() which calls cancelStore.Cancel() (acquiring mutex)
40+
// 3. That Cancel() calls the context cancel func, which closes ProcessContext().Done()
41+
// 4. The runProcessMonitoring blocks on ctx<-Done() and calls m.CancelSubprocess() again
42+
// 5. This tries to run cancelStore.Cancel() a second time while the first Cancel() is still executing
43+
// 6. go-deadlock detects deadlock
44+
if s.monitoringStopping.Swap(true) {
45+
return
46+
}
3847
s.cancelStore.Cancel()
3948
}
4049

0 commit comments

Comments
 (0)