@@ -232,6 +232,7 @@ static std::string getDiagnosticDocumentationPath() {
232
232
}
233
233
234
234
static dispatch_queue_t msgHandlingQueue;
235
+ static dispatch_queue_t requestQueue;
235
236
236
237
static void sourcekitdServer_peer_event_handler (xpc_connection_t peer,
237
238
xpc_object_t event) {
@@ -256,66 +257,65 @@ static void sourcekitdServer_peer_event_handler(xpc_connection_t peer,
256
257
assert (type == XPC_TYPE_DICTIONARY);
257
258
// Handle the message
258
259
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));
278
270
auto Responder = std::make_shared<XPCResponder>(event, peer);
279
271
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
+ });
283
287
});
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" )) {
293
295
// Ping back.
294
296
xpc_object_t reply = xpc_dictionary_create_reply (event);
295
297
xpc_release (event);
296
298
assert (reply);
297
299
xpc_connection_send_message (peer, reply);
298
300
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))) {
314
314
sourcekitd::disposeCancellationToken (/* CancellationToken=*/ cancelToken);
315
- });
316
- } else {
317
- assert ( false && " unexpected message " );
318
- }
315
+ } else {
316
+ assert ( false && " unexpected message " );
317
+ }
318
+ });
319
319
}
320
320
}
321
321
@@ -415,9 +415,13 @@ int main(int argc, const char *argv[]) {
415
415
LOG_WARN_FUNC (" getrlimit failed: " << llvm::sys::StrError ());
416
416
}
417
417
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,
419
423
QOS_CLASS_DEFAULT , 0 );
420
- msgHandlingQueue = dispatch_queue_create (" request-handling" , attr );
424
+ requestQueue = dispatch_queue_create (" request-handling" , requestQueueAttr );
421
425
422
426
xpc_main (sourcekitdServer_event_handler);
423
427
return 0 ;
0 commit comments