================
@@ -128,38 +214,157 @@ Expected<ListToolsResult> Multiplexer::HandleToolsList() 
{
 
 void Multiplexer::HandleToolsCall(const CallToolParams &params,
                                   Reply<CallToolResult> reply) {
-  Client *backend = Route();
+  if (params.name == kToolCommand)
+    return HandleCommand(params, std::move(reply));
+  if (params.name == kToolSessionsList)
+    return HandleSessionsList(std::move(reply));
+  reply(createStringError(formatv("no tool \"{0}\"", params.name)));
+}
+
+void Multiplexer::HandleCommand(const CallToolParams &params,
+                                Reply<CallToolResult> reply) {
+  json::Object args;
+  if (params.arguments)
+    if (const json::Object *object = params.arguments->getAsObject())
+      args = *object;
+
+  std::string debugger_arg;
+  if (std::optional<StringRef> debugger = args.getString("debugger"))
+    debugger_arg = debugger->str();
+
+  Client *backend = nullptr;
+  if (debugger_arg.empty()) {
+    // Default to the first session, letting the backend pick its debugger.
+    backend = First();
+    args.erase("debugger");
+  } else {
+    std::optional<RoutedURI> routed = ParseGlobalURI(debugger_arg);
+    if (!routed)
+      return reply(createStringError(
+          formatv("malformed debugger uri \"{0}\"", debugger_arg)));
+    backend = RouteToPid(routed->pid);
+    args["debugger"] = routed->local;
+  }
+
   if (!backend)
     return reply(createStringError("no debug session available"));
 
-  std::optional<StringRef> backend_tool =
-      StringSwitch<std::optional<StringRef>>(params.name)
-          .Case(kToolCommand, kBackendToolCommand)
-          .Case(kToolSessionsList, kBackendToolDebuggerList)
-          .Default(std::nullopt);
-  if (!backend_tool)
-    return reply(createStringError(formatv("no tool \"{0}\"", params.name)));
-
   CallToolParams backend_params;
-  backend_params.arguments = params.arguments;
-  backend_params.name = *backend_tool;
-
+  backend_params.name = kBackendToolCommand;
+  backend_params.arguments = json::Value(std::move(args));
   backend->ToolsCall(backend_params, std::move(reply));
 }
 
+void Multiplexer::HandleSessionsList(Reply<CallToolResult> reply) {
+  if (m_backends.empty())
+    return reply(makeTextResult(""));
+
+  struct State {
+    size_t remaining;
+    // Keyed by pid so the aggregated output is deterministic.
+    std::map<lldb::pid_t, std::string> texts;
+    std::string error;
+    Reply<CallToolResult> reply;
+  };
+  auto state = std::make_shared<State>();
+  state->remaining = m_backends.size();
+  state->reply = std::move(reply);
+
+  for (Backend &backend : m_backends) {
+    lldb::pid_t pid = backend.pid;
+    CallToolParams params;
+    params.name = kBackendToolDebuggerList;
+    backend.client->ToolsCall(
+        params, [state, pid](Expected<CallToolResult> result) {
----------------
JDevlieghere wrote:

Yes, every backend and client share the MainLoop, and transport reads dispatch 
replies synchronously on it so the callbacks are synchronized. 

https://github.com/llvm/llvm-project/pull/208827
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to