Skip to content

Commit 6fb31a1

Browse files
committed
Use of Execution and teardown sequences race with process termination
Process termination monitoring is started asynchronously with the closure which receives the Execution, meaning any use of Execution in the body to send signals, etc., may send them to a pid which no longer refers to the original process. The cleanup handler may also run after the process has already terminated. This compounds with the fix for #82 (#83) to fully resolve the race conditions.
1 parent 4211d5f commit 6fb31a1

File tree

1 file changed

+10
-11
lines changed

1 file changed

+10
-11
lines changed

Sources/Subprocess/Configuration.swift

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,30 +74,29 @@ public struct Configuration: Sendable {
7474
let pid = spawnResults.execution.processIdentifier
7575

7676
var spawnResultBox: SpawnResult?? = consume spawnResults
77+
var _spawnResult = spawnResultBox!.take()!
7778

78-
return try await withAsyncTaskCleanupHandler {
79-
var _spawnResult = spawnResultBox!.take()!
79+
let processIdentifier = _spawnResult.execution.processIdentifier
80+
81+
let result = try await withAsyncTaskCleanupHandler {
8082
let inputIO = _spawnResult.inputWriteEnd()
8183
let outputIO = _spawnResult.outputReadEnd()
8284
let errorIO = _spawnResult.errorReadEnd()
83-
let processIdentifier = _spawnResult.execution.processIdentifier
8485

85-
async let terminationStatus = try monitorProcessTermination(
86-
forProcessWithIdentifier: processIdentifier
87-
)
8886
// Body runs in the same isolation
89-
let result = try await body(_spawnResult.execution, inputIO, outputIO, errorIO)
90-
return ExecutionResult(
91-
terminationStatus: try await terminationStatus,
92-
value: result
93-
)
87+
return try await body(_spawnResult.execution, inputIO, outputIO, errorIO)
9488
} onCleanup: {
9589
// Attempt to terminate the child process
9690
await Execution.runTeardownSequence(
9791
self.platformOptions.teardownSequence,
9892
on: pid
9993
)
10094
}
95+
96+
return ExecutionResult(
97+
terminationStatus: try await monitorProcessTermination(forProcessWithIdentifier: processIdentifier),
98+
value: result
99+
)
101100
}
102101
}
103102

0 commit comments

Comments
 (0)