Skip to content

Commit d53190c

Browse files
authored
Merge pull request #58977 from ahoppen/pr-5.7/no-deadlock-cancellation
[5.7][SourceKit] Resolve a nondeterministic deadlock in SourceKit while cancelling
2 parents 25817bd + efc5e56 commit d53190c

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,38 +1150,42 @@ void ASTBuildOperation::schedule(WorkQueue Queue) {
11501150
std::string Error;
11511151
assert(!Result && "We should only be producing a result once");
11521152
ASTUnitRef AST = buildASTUnit(Error);
1153+
SmallVector<SwiftASTConsumerRef, 4> LocalConsumers;
11531154
{
11541155
llvm::sys::ScopedLock L(ConsumersAndResultMtx);
11551156
bool WasCancelled = CancellationFlag->load(std::memory_order_relaxed);
11561157
Result.emplace(AST, Error, WasCancelled);
1157-
for (auto &Consumer : Consumers) {
1158-
informConsumer(Consumer);
1159-
}
1158+
LocalConsumers = Consumers;
11601159
Consumers = {};
11611160
}
1161+
for (auto &Consumer : LocalConsumers) {
1162+
informConsumer(Consumer);
1163+
}
11621164
DidFinishCallback();
11631165
},
11641166
/*isStackDeep=*/true);
11651167
}
11661168

11671169
bool ASTBuildOperation::addConsumer(SwiftASTConsumerRef Consumer) {
1168-
llvm::sys::ScopedLock L(ConsumersAndResultMtx);
1169-
if (isCancelled()) {
1170-
return false;
1171-
}
1172-
if (Result) {
1173-
informConsumer(Consumer);
1174-
} else {
1170+
{
1171+
llvm::sys::ScopedLock L(ConsumersAndResultMtx);
1172+
if (isCancelled()) {
1173+
return false;
1174+
}
1175+
if (Result) {
1176+
informConsumer(Consumer);
1177+
return true;
1178+
}
11751179
assert(OperationState != State::Finished);
1176-
auto WeakThis = std::weak_ptr<ASTBuildOperation>(shared_from_this());
11771180
Consumers.push_back(Consumer);
1178-
Consumer->setCancellationRequestCallback(
1179-
[WeakThis](SwiftASTConsumerRef Consumer) {
1180-
if (auto This = WeakThis.lock()) {
1181-
This->requestConsumerCancellation(Consumer);
1182-
}
1183-
});
11841181
}
1182+
auto WeakThis = std::weak_ptr<ASTBuildOperation>(shared_from_this());
1183+
Consumer->setCancellationRequestCallback(
1184+
[WeakThis](SwiftASTConsumerRef Consumer) {
1185+
if (auto This = WeakThis.lock()) {
1186+
This->requestConsumerCancellation(Consumer);
1187+
}
1188+
});
11851189
return true;
11861190
}
11871191

0 commit comments

Comments
 (0)