@@ -135,8 +135,9 @@ class ASTUnit : public SourceKit::ThreadSafeRefCountedBase<ASTUnit> {
135
135
typedef IntrusiveRefCntPtr<ASTUnit> ASTUnitRef;
136
136
137
137
class SwiftASTConsumer : public std ::enable_shared_from_this<SwiftASTConsumer> {
138
- // / Mutex guarding all accesses to CancellationRequestCallback
139
- llvm::sys::Mutex CancellationRequestCallbackMtx;
138
+ // / Mutex guarding all accesses to \c CancellationRequestCallback and \c
139
+ // / IsCancelled.
140
+ llvm::sys::Mutex CancellationRequestCallbackAndIsCancelledMtx;
140
141
141
142
// / A callback that informs the \c ASTBuildOperation, which is producing the
142
143
// / AST for this consumer, that the consumer is no longer of interest. Calling
@@ -160,12 +161,17 @@ class SwiftASTConsumer : public std::enable_shared_from_this<SwiftASTConsumer> {
160
161
// / cause the \c ASTBuildOperation to be cancelled if no other consumer is
161
162
// / depending on it.
162
163
void requestCancellation () {
163
- llvm::sys::ScopedLock L (CancellationRequestCallbackMtx);
164
- IsCancelled = true ;
165
- if (CancellationRequestCallback.has_value ()) {
166
- (*CancellationRequestCallback)(shared_from_this ());
164
+ Optional<std::function<void (std::shared_ptr<SwiftASTConsumer>)>>
165
+ CallbackToCall;
166
+ {
167
+ llvm::sys::ScopedLock L (CancellationRequestCallbackAndIsCancelledMtx);
168
+ IsCancelled = true ;
169
+ CallbackToCall = CancellationRequestCallback;
167
170
CancellationRequestCallback = None;
168
171
}
172
+ if (CallbackToCall.has_value ()) {
173
+ (*CallbackToCall)(shared_from_this ());
174
+ }
169
175
}
170
176
171
177
// / Set a cancellation request callback that informs a \c ASTBuildOperation
@@ -177,20 +183,26 @@ class SwiftASTConsumer : public std::enable_shared_from_this<SwiftASTConsumer> {
177
183
// / called, \c NewCallback will be called immediately.
178
184
void setCancellationRequestCallback (
179
185
std::function<void (std::shared_ptr<SwiftASTConsumer>)> NewCallback) {
180
- llvm::sys::ScopedLock L (CancellationRequestCallbackMtx);
181
- assert (!CancellationRequestCallback.has_value () &&
182
- " Can't set two cancellation callbacks on a SwiftASTConsumer" );
183
- if (IsCancelled) {
186
+ bool ShouldCallCallback = false ;
187
+ {
188
+ llvm::sys::ScopedLock L (CancellationRequestCallbackAndIsCancelledMtx);
189
+ assert (!CancellationRequestCallback.has_value () &&
190
+ " Can't set two cancellation callbacks on a SwiftASTConsumer" );
191
+ if (IsCancelled) {
192
+ ShouldCallCallback = true ;
193
+ } else {
194
+ CancellationRequestCallback = NewCallback;
195
+ }
196
+ }
197
+ if (ShouldCallCallback) {
184
198
NewCallback (shared_from_this ());
185
- } else {
186
- CancellationRequestCallback = NewCallback;
187
199
}
188
200
}
189
201
190
202
// / Removes the cancellation request callback previously set by \c
191
203
// / setCancellationRequestCallback.
192
204
void removeCancellationRequestCallback () {
193
- llvm::sys::ScopedLock L (CancellationRequestCallbackMtx );
205
+ llvm::sys::ScopedLock L (CancellationRequestCallbackAndIsCancelledMtx );
194
206
CancellationRequestCallback = None;
195
207
}
196
208
0 commit comments