Skip to content

Commit 025e919

Browse files
authored
Merge pull request swiftlang#42258 from ahoppen/pr/no-deadlock-cancellation
[SourceKit] Resolve a nondeterministic deadlock in SourceKit while cancelling
2 parents b52257e + d7eada4 commit 025e919

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
@@ -1155,38 +1155,42 @@ void ASTBuildOperation::schedule(WorkQueue Queue) {
11551155
std::string Error;
11561156
assert(!Result && "We should only be producing a result once");
11571157
ASTUnitRef AST = buildASTUnit(Error);
1158+
SmallVector<SwiftASTConsumerRef, 4> LocalConsumers;
11581159
{
11591160
llvm::sys::ScopedLock L(ConsumersAndResultMtx);
11601161
bool WasCancelled = CancellationFlag->load(std::memory_order_relaxed);
11611162
Result.emplace(AST, Error, WasCancelled);
1162-
for (auto &Consumer : Consumers) {
1163-
informConsumer(Consumer);
1164-
}
1163+
LocalConsumers = Consumers;
11651164
Consumers = {};
11661165
}
1166+
for (auto &Consumer : LocalConsumers) {
1167+
informConsumer(Consumer);
1168+
}
11671169
DidFinishCallback();
11681170
},
11691171
/*isStackDeep=*/true);
11701172
}
11711173

11721174
bool ASTBuildOperation::addConsumer(SwiftASTConsumerRef Consumer) {
1173-
llvm::sys::ScopedLock L(ConsumersAndResultMtx);
1174-
if (isCancelled()) {
1175-
return false;
1176-
}
1177-
if (Result) {
1178-
informConsumer(Consumer);
1179-
} else {
1175+
{
1176+
llvm::sys::ScopedLock L(ConsumersAndResultMtx);
1177+
if (isCancelled()) {
1178+
return false;
1179+
}
1180+
if (Result) {
1181+
informConsumer(Consumer);
1182+
return true;
1183+
}
11801184
assert(OperationState != State::Finished);
1181-
auto WeakThis = std::weak_ptr<ASTBuildOperation>(shared_from_this());
11821185
Consumers.push_back(Consumer);
1183-
Consumer->setCancellationRequestCallback(
1184-
[WeakThis](SwiftASTConsumerRef Consumer) {
1185-
if (auto This = WeakThis.lock()) {
1186-
This->requestConsumerCancellation(Consumer);
1187-
}
1188-
});
11891186
}
1187+
auto WeakThis = std::weak_ptr<ASTBuildOperation>(shared_from_this());
1188+
Consumer->setCancellationRequestCallback(
1189+
[WeakThis](SwiftASTConsumerRef Consumer) {
1190+
if (auto This = WeakThis.lock()) {
1191+
This->requestConsumerCancellation(Consumer);
1192+
}
1193+
});
11901194
return true;
11911195
}
11921196

0 commit comments

Comments
 (0)