================
@@ -128,38 +214,157 @@ Expected<ListToolsResult> Multiplexer::HandleToolsList()
{
void Multiplexer::HandleToolsCall(const CallToolParams ¶ms,
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 ¶ms,
+ 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