Skip to content

Commit 581ce83

Browse files
committed
Use dispatch barriers for open/edit/close on the message handling queue
1 parent 74fd209 commit 581ce83

File tree

4 files changed

+69
-22
lines changed

4 files changed

+69
-22
lines changed

tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "sourcekitd/DictionaryKeys.h"
1314
#include "sourcekitd/Internal.h"
1415
#include "sourcekitd/Service.h"
1516

@@ -34,6 +35,8 @@
3435

3536
using namespace SourceKit;
3637

38+
WorkQueue *msgHandlingQueue = nullptr;
39+
3740
static void postNotification(sourcekitd_response_t Notification);
3841

3942
static void getToolchainPrefixPath(llvm::SmallVectorImpl<char> &Path) {
@@ -96,6 +99,9 @@ static std::string getDiagnosticDocumentationPath() {
9699
}
97100

98101
void sourcekitd_initialize(void) {
102+
assert(msgHandlingQueue == nullptr && "Cannot initialize service twice");
103+
msgHandlingQueue = new WorkQueue(WorkQueue::Dequeuing::Concurrent,
104+
"sourcekitdInProc.msgHandlingQueue");
99105
if (sourcekitd::initializeClient()) {
100106
LOG_INFO_FUNC(High, "initializing");
101107
sourcekitd::initializeService(getSwiftExecutablePath(), getRuntimeLibPath(),
@@ -152,9 +158,12 @@ void sourcekitd_send_request(sourcekitd_object_t req,
152158
*out_handle = request_handle;
153159
}
154160

161+
sourcekitd_uid_t ReqUID =
162+
sourcekitd::RequestDict(req).getUID(sourcekitd::KeyRequest);
163+
155164
sourcekitd_request_retain(req);
156165
receiver = Block_copy(receiver);
157-
WorkQueue::dispatchConcurrent([=] {
166+
auto handler = [=] {
158167
sourcekitd::handleRequest(req, /*CancellationToken=*/request_handle,
159168
[=](sourcekitd_response_t resp) {
160169
// The receiver accepts ownership of the
@@ -163,7 +172,13 @@ void sourcekitd_send_request(sourcekitd_object_t req,
163172
Block_release(receiver);
164173
});
165174
sourcekitd_request_release(req);
166-
});
175+
};
176+
177+
if (sourcekitd::requestIsBarrier(ReqUID)) {
178+
msgHandlingQueue->dispatchBarrier(handler);
179+
} else {
180+
msgHandlingQueue->dispatchConcurrent(handler);
181+
}
167182
}
168183

169184
void sourcekitd_cancel_request(sourcekitd_request_handle_t handle) {

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

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "sourcekitd/DictionaryKeys.h"
1314
#include "sourcekitd/Internal-XPC.h"
15+
#include "sourcekitd/Internal.h"
1416
#include "sourcekitd/Logging.h"
1517
#include "sourcekitd/Service.h"
1618

@@ -255,43 +257,57 @@ static void sourcekitdServer_peer_event_handler(xpc_connection_t peer,
255257
assert(type == XPC_TYPE_DICTIONARY);
256258
// Handle the message
257259
xpc_retain(event);
258-
dispatch_async(msgHandlingQueue, ^{
259-
if (xpc_object_t contents =
260-
xpc_dictionary_get_value(event, xpc::KeyMsg)) {
260+
if (xpc_object_t contents = xpc_dictionary_get_value(event, xpc::KeyMsg)) {
261+
assert(xpc_get_type(contents) == XPC_TYPE_ARRAY);
262+
sourcekitd_object_t req = xpc_array_get_value(contents, 0);
263+
264+
sourcekitd_uid_t ReqUID = RequestDict(req).getUID(KeyRequest);
265+
266+
void (^handler)(void) = ^{
261267
SourceKitCancellationToken cancelToken =
262268
reinterpret_cast<SourceKitCancellationToken>(
263269
xpc_dictionary_get_uint64(event, xpc::KeyCancelToken));
264270
auto Responder = std::make_shared<XPCResponder>(event, peer);
265271
xpc_release(event);
266272

267-
assert(xpc_get_type(contents) == XPC_TYPE_ARRAY);
268-
sourcekitd_object_t req = xpc_array_get_value(contents, 0);
269273
sourcekitd::handleRequest(req, /*CancellationToken=*/cancelToken,
270274
[Responder](sourcekitd_response_t response) {
271275
Responder->sendReply(response);
272276
});
273-
} else if (xpc_object_t contents =
274-
xpc_dictionary_get_value(event, "ping")) {
277+
};
278+
279+
if (requestIsBarrier(ReqUID)) {
280+
dispatch_barrier_async(msgHandlingQueue, handler);
281+
} else {
282+
dispatch_async(msgHandlingQueue, handler);
283+
}
284+
} else if (xpc_object_t contents =
285+
xpc_dictionary_get_value(event, "ping")) {
286+
dispatch_async(msgHandlingQueue, ^{
275287
// Ping back.
276288
xpc_object_t reply = xpc_dictionary_create_reply(event);
277289
xpc_release(event);
278290
assert(reply);
279291
xpc_connection_send_message(peer, reply);
280292
xpc_release(reply);
281-
} else if (SourceKitCancellationToken cancelToken =
282-
reinterpret_cast<SourceKitCancellationToken>(
283-
xpc_dictionary_get_uint64(event,
284-
xpc::KeyCancelRequest))) {
293+
});
294+
} else if (SourceKitCancellationToken cancelToken =
295+
reinterpret_cast<SourceKitCancellationToken>(
296+
xpc_dictionary_get_uint64(event,
297+
xpc::KeyCancelRequest))) {
298+
dispatch_async(msgHandlingQueue, ^{
285299
sourcekitd::cancelRequest(/*CancellationToken=*/cancelToken);
286-
} else if (SourceKitCancellationToken cancelToken =
287-
reinterpret_cast<SourceKitCancellationToken>(
288-
xpc_dictionary_get_uint64(
289-
event, xpc::KeyDisposeRequestHandle))) {
300+
});
301+
} else if (SourceKitCancellationToken cancelToken =
302+
reinterpret_cast<SourceKitCancellationToken>(
303+
xpc_dictionary_get_uint64(
304+
event, xpc::KeyDisposeRequestHandle))) {
305+
dispatch_async(msgHandlingQueue, ^{
290306
sourcekitd::disposeCancellationToken(/*CancellationToken=*/cancelToken);
291-
} else {
292-
assert(false && "unexpected message");
293-
}
294-
});
307+
});
308+
} else {
309+
assert(false && "unexpected message");
310+
}
295311
}
296312
}
297313

tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ struct VariantFunctions {
229229
const void *(*data_get_ptr)(sourcekitd_variant_t obj);
230230
};
231231

232-
}
232+
/// Whether a request with the given UID should be dispatched as a barrier onto
233+
/// the message handling queue.
234+
bool requestIsBarrier(sourcekitd_uid_t reqUID);
233235

236+
} // namespace sourcekitd
234237
#endif

tools/SourceKit/tools/sourcekitd/lib/API/UIDHandling.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,16 @@ UIdent sourcekitd::UIdentFromSKDUID(sourcekitd_uid_t uid) {
6666

6767
return UIdent::getFromOpaqueValue(uid);
6868
}
69+
70+
static sourcekitd_uid_t RequestEditorOpen =
71+
sourcekitd::SKDUIDFromUIdent(UIdent("source.request.editor.open"));
72+
static sourcekitd_uid_t RequestEditorClose =
73+
sourcekitd::SKDUIDFromUIdent(UIdent("source.request.editor.close"));
74+
static sourcekitd_uid_t RequestEditorReplaceText =
75+
sourcekitd::SKDUIDFromUIdent(UIdent("source.request.editor.replacetext"));
76+
77+
bool sourcekitd::requestIsBarrier(sourcekitd_uid_t reqUID) {
78+
// TODO: Do we also need to add barriers for interface open etc?
79+
return reqUID == RequestEditorOpen || reqUID == RequestEditorReplaceText ||
80+
reqUID == RequestEditorClose;
81+
}

0 commit comments

Comments
 (0)