================
@@ -5058,72 +5053,144 @@ int main(int argc, char *argv[]) {
   auto terminate_debugger =
       llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); });
 
-  StreamDescriptor input;
-  StreamDescriptor output;
-  std::FILE *redirectOut = nullptr;
-  std::FILE *redirectErr = nullptr;
-  if (portno != -1) {
-    printf("Listening on port %i...\n", portno);
-    SOCKET socket_fd = AcceptConnection(log.get(), portno);
-    if (socket_fd < 0)
-      return EXIT_FAILURE;
+  std::vector<std::string> pre_init_commands;
+  for (const std::string &arg :
+       input_args.getAllArgValues(OPT_pre_init_command)) {
+    pre_init_commands.push_back(arg);
+  }
 
-    input = StreamDescriptor::from_socket(socket_fd, true);
-    output = StreamDescriptor::from_socket(socket_fd, false);
-  } else {
-#if defined(_WIN32)
-    // Windows opens stdout and stdin in text mode which converts \n to 13,10
-    // while the value is just 10 on Darwin/Linux. Setting the file mode to
-    // binary fixes this.
-    int result = _setmode(fileno(stdout), _O_BINARY);
-    assert(result);
-    result = _setmode(fileno(stdin), _O_BINARY);
-    UNUSED_IF_ASSERT_DISABLED(result);
-    assert(result);
-#endif
+  auto RunDAP = [](llvm::StringRef program_path, ReplMode repl_mode,
+                   std::vector<std::string> pre_init_commands,
+                   std::ofstream *log, std::string name, StreamDescriptor 
input,
+                   StreamDescriptor output, std::FILE *redirectOut = nullptr,
+                   std::FILE *redirectErr = nullptr) -> bool {
+    DAP dap = DAP(name, program_path, log, std::move(input), std::move(output),
+                  repl_mode, pre_init_commands);
 
-    int stdout_fd = DuplicateFileDescriptor(fileno(stdout));
-    if (stdout_fd == -1) {
+    // stdout/stderr redirection to the IDE's console
+    if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
       llvm::logAllUnhandledErrors(
-          llvm::errorCodeToError(llvm::errnoAsErrorCode()), llvm::errs(),
-          "Failed to configure stdout redirect: ");
+          std::move(Err), llvm::errs(),
+          "Failed to configure lldb-dap IO operations: ");
+      return false;
+    }
+
+    RegisterRequestCallbacks(dap);
+
+    // used only by TestVSCode_redirection_to_console.py
+    if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
+      redirection_test();
+
+    if (auto Err = dap.Loop()) {
+      std::string errorMessage = llvm::toString(std::move(Err));
+      if (log)
+        *log << "Transport Error: " << errorMessage << "\n";
+      return false;
+    }
+    return true;
+  };
+
+  if (!connection.empty()) {
+    auto maybeProtoclAndName = validateConnection(connection);
+    if (auto Err = maybeProtoclAndName.takeError()) {
+      llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(),
+                                  "Invalid connection: ");
       return EXIT_FAILURE;
     }
 
-    redirectOut = stdout;
-    redirectErr = stderr;
+    Socket::SocketProtocol protocol;
+    std::string name;
+    std::tie(protocol, name) = *maybeProtoclAndName;
 
-    input = StreamDescriptor::from_file(fileno(stdin), false);
-    output = StreamDescriptor::from_file(stdout_fd, false);
-  }
+    Status error;
+    std::unique_ptr<Socket> listener = Socket::Create(protocol, error);
+    if (error.Fail()) {
+      llvm::logAllUnhandledErrors(error.takeError(), llvm::errs(),
+                                  "Failed to create socket listener: ");
+      return EXIT_FAILURE;
+    }
 
-  DAP dap = DAP(program_path.str(), log.get(), default_repl_mode,
-                std::move(input), std::move(output));
+    error = listener->Listen(name, /* backlog */ 5);
+    if (error.Fail()) {
+      llvm::logAllUnhandledErrors(error.takeError(), llvm::errs(),
+                                  "Failed to listen for connections: ");
+      return EXIT_FAILURE;
+    }
 
-  // stdout/stderr redirection to the IDE's console
-  if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
-    llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(),
-                                "Failed to configure lldb-dap IO operations: 
");
-    return EXIT_FAILURE;
-  }
+    std::string address =
+        llvm::join(listener->GetListeningConnectionURI(), ", ");
+    if (log)
+      *log << "started with connection listeners " << address << "\n";
+
+    llvm::outs() << "Listening for: " << address << "\n";
+    // Ensure listening address are flushed for calles to retrieve the resolve
+    // address.
+    llvm::outs().flush();
+
+    llvm::DefaultThreadPool pool(llvm::optimal_concurrency());
----------------
labath wrote:

Are you sure about that? I haven't tried this, but looking at the source code, 
it definitely looks like it is [limiting 
something](https://github.com/llvm/llvm-project/blob/409fa785d99b3e9f8210b72641d58947e6687fb1/llvm/lib/Support/Threading.cpp#L60).
 And although the implementation appears to be stubbed out, it looks like it 
has some ambition to mess with [cpu 
affinities](https://github.com/llvm/llvm-project/blob/409fa785d99b3e9f8210b72641d58947e6687fb1/llvm/include/llvm/Support/Threading.h#L135)
 which, I guess, is fine if you have a a lot of work to do and you want to 
avoid cpu migrations, but maybe not so fine when in practice you just have one 
task most of the time, and you want to make sure that task gets access to all 
cpus.

I have feeling this class just wasn't designed for this use case. We may need 
to roll our own solution. The detached thread approach is "almost" right in 
that we don't care about a single thread exiting. What we want to wait for is 
*all* threads to exit. So maybe have a counter of active threads which is 
decreased (and signaled with 
[std::notify_all_at_thread_exit](https://en.cppreference.com/w/cpp/thread/notify_all_at_thread_exit)?)
 when the thread exits?

https://github.com/llvm/llvm-project/pull/116392
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to