Skip to content

Commit 23e2f34

Browse files
authored
Merge pull request #66441 from ahoppen/ahoppen/deadlock
[SourceKit] Jump to a background queue before executing `SKDUIDFromUIdent`
2 parents 7b74f72 + f0ad258 commit 23e2f34

File tree

1 file changed

+56
-52
lines changed

1 file changed

+56
-52
lines changed

tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XPCService.cpp

+56-52
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ static std::string getDiagnosticDocumentationPath() {
232232
}
233233

234234
static dispatch_queue_t msgHandlingQueue;
235+
static dispatch_queue_t requestQueue;
235236

236237
static void sourcekitdServer_peer_event_handler(xpc_connection_t peer,
237238
xpc_object_t event) {
@@ -256,66 +257,65 @@ static void sourcekitdServer_peer_event_handler(xpc_connection_t peer,
256257
assert(type == XPC_TYPE_DICTIONARY);
257258
// Handle the message
258259
xpc_retain(event);
259-
if (xpc_object_t contents = xpc_dictionary_get_value(event, xpc::KeyMsg)) {
260-
assert(xpc_get_type(contents) == XPC_TYPE_ARRAY);
261-
sourcekitd_object_t req = xpc_array_get_value(contents, 0);
262-
263-
void (^handler)(void) = ^{
264-
SourceKitCancellationToken cancelToken =
265-
reinterpret_cast<SourceKitCancellationToken>(
266-
xpc_dictionary_get_uint64(event, xpc::KeyCancelToken));
267-
auto Responder = std::make_shared<XPCResponder>(event, peer);
268-
xpc_release(event);
269-
270-
sourcekitd::handleRequest(req, /*CancellationToken=*/cancelToken,
271-
[Responder](sourcekitd_response_t response) {
272-
Responder->sendReply(response);
273-
});
274-
};
275-
276-
if (sourcekitd::requestIsEnableBarriers(req)) {
277-
dispatch_barrier_async(msgHandlingQueue, ^{
260+
dispatch_async(msgHandlingQueue, ^{
261+
if (xpc_object_t contents =
262+
xpc_dictionary_get_value(event, xpc::KeyMsg)) {
263+
assert(xpc_get_type(contents) == XPC_TYPE_ARRAY);
264+
sourcekitd_object_t req = xpc_array_get_value(contents, 0);
265+
266+
void (^handler)(void) = ^{
267+
SourceKitCancellationToken cancelToken =
268+
reinterpret_cast<SourceKitCancellationToken>(
269+
xpc_dictionary_get_uint64(event, xpc::KeyCancelToken));
278270
auto Responder = std::make_shared<XPCResponder>(event, peer);
279271
xpc_release(event);
280-
RequestBarriersEnabled = true;
281-
sourcekitd::sendBarriersEnabledResponse([Responder](sourcekitd_response_t response) {
282-
Responder->sendReply(response);
272+
273+
sourcekitd::handleRequest(req, /*CancellationToken=*/cancelToken,
274+
[Responder](sourcekitd_response_t response) {
275+
Responder->sendReply(response);
276+
});
277+
};
278+
279+
if (sourcekitd::requestIsEnableBarriers(req)) {
280+
dispatch_barrier_async(requestQueue, ^{
281+
auto Responder = std::make_shared<XPCResponder>(event, peer);
282+
xpc_release(event);
283+
RequestBarriersEnabled = true;
284+
sourcekitd::sendBarriersEnabledResponse([Responder](sourcekitd_response_t response) {
285+
Responder->sendReply(response);
286+
});
283287
});
284-
});
285-
} else if (RequestBarriersEnabled && sourcekitd::requestIsBarrier(req)) {
286-
dispatch_barrier_async(msgHandlingQueue, handler);
287-
} else {
288-
dispatch_async(msgHandlingQueue, handler);
289-
}
290-
} else if (xpc_object_t contents =
291-
xpc_dictionary_get_value(event, "ping")) {
292-
dispatch_async(msgHandlingQueue, ^{
288+
} else if (RequestBarriersEnabled && sourcekitd::requestIsBarrier(req)) {
289+
dispatch_barrier_async(requestQueue, handler);
290+
} else {
291+
dispatch_async(requestQueue, handler);
292+
}
293+
} else if (xpc_object_t contents =
294+
xpc_dictionary_get_value(event, "ping")) {
293295
// Ping back.
294296
xpc_object_t reply = xpc_dictionary_create_reply(event);
295297
xpc_release(event);
296298
assert(reply);
297299
xpc_connection_send_message(peer, reply);
298300
xpc_release(reply);
299-
});
300-
} else if (SourceKitCancellationToken cancelToken =
301-
reinterpret_cast<SourceKitCancellationToken>(
302-
xpc_dictionary_get_uint64(event,
303-
xpc::KeyCancelRequest))) {
304-
// Execute cancellation on a queue other than `msgHandling` so that we
305-
// don’t block the cancellation of a request with a barrier
306-
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
307-
sourcekitd::cancelRequest(/*CancellationToken=*/cancelToken);
308-
});
309-
} else if (SourceKitCancellationToken cancelToken =
310-
reinterpret_cast<SourceKitCancellationToken>(
311-
xpc_dictionary_get_uint64(
312-
event, xpc::KeyDisposeRequestHandle))) {
313-
dispatch_async(msgHandlingQueue, ^{
301+
} else if (SourceKitCancellationToken cancelToken =
302+
reinterpret_cast<SourceKitCancellationToken>(
303+
xpc_dictionary_get_uint64(event,
304+
xpc::KeyCancelRequest))) {
305+
// Execute cancellation on a queue other than `msgHandling` so that we
306+
// don’t block the cancellation of a request with a barrier
307+
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
308+
sourcekitd::cancelRequest(/*CancellationToken=*/cancelToken);
309+
});
310+
} else if (SourceKitCancellationToken cancelToken =
311+
reinterpret_cast<SourceKitCancellationToken>(
312+
xpc_dictionary_get_uint64(
313+
event, xpc::KeyDisposeRequestHandle))) {
314314
sourcekitd::disposeCancellationToken(/*CancellationToken=*/cancelToken);
315-
});
316-
} else {
317-
assert(false && "unexpected message");
318-
}
315+
} else {
316+
assert(false && "unexpected message");
317+
}
318+
});
319319
}
320320
}
321321

@@ -415,9 +415,13 @@ int main(int argc, const char *argv[]) {
415415
LOG_WARN_FUNC("getrlimit failed: " << llvm::sys::StrError());
416416
}
417417

418-
auto attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT,
418+
auto msgHandlingQueueAttr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL,
419+
QOS_CLASS_DEFAULT, 0);
420+
msgHandlingQueue = dispatch_queue_create("message-handling", msgHandlingQueueAttr);
421+
422+
auto requestQueueAttr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT,
419423
QOS_CLASS_DEFAULT, 0);
420-
msgHandlingQueue = dispatch_queue_create("request-handling", attr);
424+
requestQueue = dispatch_queue_create("request-handling", requestQueueAttr);
421425

422426
xpc_main(sourcekitdServer_event_handler);
423427
return 0;

0 commit comments

Comments
 (0)