@@ -232,6 +232,7 @@ static std::string getDiagnosticDocumentationPath() {
232232}
233233
234234static dispatch_queue_t msgHandlingQueue;
235+ static dispatch_queue_t requestQueue;
235236
236237static 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