[clangd-dev] Transport layer abstraction

Sam McCall via clangd-dev clangd-dev at lists.llvm.org
Wed Sep 12 15:17:46 PDT 2018

On Wed, Sep 12, 2018 at 6:20 PM Jan Korous via clangd-dev <
clangd-dev at lists.llvm.org> wrote:

> Hi all,
> We had an internal discussion about XPC use with clangd and the result is
> that XPC-based transport layer in clangd is a hard requirement. This
> effectively means that the adapter approach is not feasible and I am
> looking into the transport layer abstraction Sam proposed earlier (
> https://reviews.llvm.org/D49389). Sorry for the trouble!
No problem! (And sorry if I've been a bit unresponsive!)

There is a difficulty with designing an abstraction over transport layer
> due to XPC API requiring client code to hand control over. It's necessary
> for XPC server to call xpc_main() with a message handling callback:
> xpc_main(connection_handler);
> But XPC is running it's own message loop inside xpc_main() which is
> supposed to never return (in case of failure exit() is called) which makes
> it difficult to have common interface for JSON RPC and XPC.
> Unless I am mistaken that means that the message loop (Transport::loop(),
> ClangdLSPServer::run()) can't be part of generic code.
> I am curious what are other people's thoughts on this?
That makes sense to me, but I don't think a common interface is impossible.
I noticed this in your patch, and in D49389 the idea (which I didn't spell
out) was that the XPC transport's loop() would call xpc_main and never
Transport::loop() is specific to a transport, it doesn't need to be part of
generic code. ClangdLSPServer::run() ends up calling Transport::loop(), so
it could be common code.

It'd look something like:

static Transport::MessageHandler *IncomingXPCMessages; // XPC -> clangd
static xpc_connection_t *XPCConnection; // clangd -> XPC

XPCTransport::loop(MessageHandler &M) {
  IncomingXPCMessages = &M;

static void XPCEntrypoint(xpc_connection_t Conn) {
  // I don't remember how an XPC server looks
  // i guess you're reading editor->clangd messages in a loop?
  for (;;) {
    // lets say you parsed a notification
    std::string name = ...;
    json::Value args = xpcToJSON(...);
    IncomingXPCMessages->notify(name, args); // send the notification to

XPCTransport::notify(StringRef name, json::Value args) {
  xpc_object_t XPCNotification = encodeNotificationForXPCSomehow(name,
  xpc_connection_send(*XPCConnection, XPCNotification);


> I tried to come up with some reasonable abstraction but I am probably
> already anchored by my previous work (https://reviews.llvm.org/D48559) -
> all my design ideas tend to go in the direction of abstraction over
> JsonOutput and custom dispatchers (StdIoDispatcher/XPCDispatcher).
> Cheers,
> Jan
> _______________________________________________
> clangd-dev mailing list
> clangd-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/clangd-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/clangd-dev/attachments/20180913/5acff4ba/attachment.html>

More information about the clangd-dev mailing list