Skip to content
Permalink
Browse files
Merge pull request #42258 from ahoppen/pr/no-deadlock-cancellation
[SourceKit] Resolve a nondeterministic deadlock in SourceKit while cancelling
  • Loading branch information
ahoppen committed May 19, 2022
2 parents b52257e + d7eada4 commit 025e919b84efd1e1d35fc57609d37dd5aecb0d29
Showing 1 changed file with 21 additions and 17 deletions.
@@ -1155,38 +1155,42 @@ void ASTBuildOperation::schedule(WorkQueue Queue) {
std::string Error;
assert(!Result && "We should only be producing a result once");
ASTUnitRef AST = buildASTUnit(Error);
SmallVector<SwiftASTConsumerRef, 4> LocalConsumers;
{
llvm::sys::ScopedLock L(ConsumersAndResultMtx);
bool WasCancelled = CancellationFlag->load(std::memory_order_relaxed);
Result.emplace(AST, Error, WasCancelled);
for (auto &Consumer : Consumers) {
informConsumer(Consumer);
}
LocalConsumers = Consumers;
Consumers = {};
}
for (auto &Consumer : LocalConsumers) {
informConsumer(Consumer);
}
DidFinishCallback();
},
/*isStackDeep=*/true);
}

bool ASTBuildOperation::addConsumer(SwiftASTConsumerRef Consumer) {
llvm::sys::ScopedLock L(ConsumersAndResultMtx);
if (isCancelled()) {
return false;
}
if (Result) {
informConsumer(Consumer);
} else {
{
llvm::sys::ScopedLock L(ConsumersAndResultMtx);
if (isCancelled()) {
return false;
}
if (Result) {
informConsumer(Consumer);
return true;
}
assert(OperationState != State::Finished);
auto WeakThis = std::weak_ptr<ASTBuildOperation>(shared_from_this());
Consumers.push_back(Consumer);
Consumer->setCancellationRequestCallback(
[WeakThis](SwiftASTConsumerRef Consumer) {
if (auto This = WeakThis.lock()) {
This->requestConsumerCancellation(Consumer);
}
});
}
auto WeakThis = std::weak_ptr<ASTBuildOperation>(shared_from_this());
Consumer->setCancellationRequestCallback(
[WeakThis](SwiftASTConsumerRef Consumer) {
if (auto This = WeakThis.lock()) {
This->requestConsumerCancellation(Consumer);
}
});
return true;
}

0 comments on commit 025e919

Please sign in to comment.