Skip to content

Commit a78bc5e

Browse files
authored
Merge pull request #2152 from ahoppen/cancellation-missed
Fix race condition that causes task cancellation to be missed in `TaskScheduler`
2 parents f3153ba + 47a940d commit a78bc5e

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

Sources/SemanticIndex/PreparationTaskDescription.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@ package struct PreparationTaskDescription: IndexTaskDescription {
105105
do {
106106
try await buildSystemManager.prepare(targets: Set(targetsToPrepare))
107107
} catch {
108-
logger.error(
109-
"Preparation failed: \(error.forLogging)"
110-
)
108+
logger.error("Preparation failed: \(error.forLogging)")
111109
}
112110
await hooks.preparationTaskDidFinish?(self)
113111
if !Task.isCancelled {

Sources/SemanticIndex/TaskScheduler.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,14 @@ package actor QueuedTask<TaskDescription: TaskDescriptionProtocol> {
249249
_isExecuting.value = true
250250
executionTask = task
251251
executionTaskCreatedContinuation.yield(task)
252+
if self.resultTaskCancelled.value {
253+
// The queued task might have been cancelled after the execution ask was started but before the task was yielded
254+
// to `executionTaskCreatedContinuation`. In that case the result task will simply cancel the await on the
255+
// `executionTaskCreatedStream` and hence not call `valuePropagatingCancellation` on the execution task. This
256+
// means that the queued task cancellation wouldn't be propagated to the execution task. To address this, check if
257+
// `resultTaskCancelled` was set and, if so, explicitly cancel the execution task here.
258+
task.cancel()
259+
}
252260
await executionStateChangedCallback?(self, .executing)
253261
return await task.value
254262
}

0 commit comments

Comments
 (0)