[Lldb-commits] [lldb] [lldb-dap] Ensure the IO forwarding threads are managed by the DAP object lifecycle. (PR #120457)
John Harrison via lldb-commits
lldb-commits at lists.llvm.org
Mon Dec 23 12:47:10 PST 2024
================
@@ -17,47 +19,59 @@
#include "OutputRedirector.h"
#include "llvm/ADT/StringRef.h"
-using namespace llvm;
+using lldb_private::Pipe;
+using lldb_private::Status;
+using llvm::createStringError;
+using llvm::Error;
+using llvm::Expected;
+using llvm::StringRef;
namespace lldb_dap {
-Error RedirectFd(int fd, std::function<void(llvm::StringRef)> callback) {
- int new_fd[2];
-#if defined(_WIN32)
- if (_pipe(new_fd, 4096, O_TEXT) == -1) {
-#else
- if (pipe(new_fd) == -1) {
-#endif
- int error = errno;
- return createStringError(inconvertibleErrorCode(),
- "Couldn't create new pipe for fd %d. %s", fd,
- strerror(error));
- }
+Expected<int> OutputRedirector::GetWriteFileDescriptor() {
+ if (!m_pipe.CanWrite())
+ return createStringError(std::errc::bad_file_descriptor,
+ "write handle is not open for writing");
+ return m_pipe.GetWriteFileDescriptor();
+}
- if (dup2(new_fd[1], fd) == -1) {
- int error = errno;
- return createStringError(inconvertibleErrorCode(),
- "Couldn't override the fd %d. %s", fd,
- strerror(error));
- }
+Error OutputRedirector::RedirectTo(std::function<void(StringRef)> callback) {
+ Status status = m_pipe.CreateNew(/*child_process_inherit=*/false);
+ if (status.Fail())
+ return status.takeError();
- int read_fd = new_fd[0];
- std::thread t([read_fd, callback]() {
+ m_forwarder = std::thread([this, callback]() {
char buffer[OutputBufferSize];
- while (true) {
- ssize_t bytes_count = read(read_fd, &buffer, sizeof(buffer));
- if (bytes_count == 0)
- return;
- if (bytes_count == -1) {
- if (errno == EAGAIN || errno == EINTR)
- continue;
+ while (m_pipe.CanRead() && !m_stopped) {
+ size_t bytes_read;
+ Status status = m_pipe.Read(&buffer, sizeof(buffer), bytes_read);
+ if (status.Fail())
+ continue;
+
+ // EOF detected
+ if (bytes_read == 0)
break;
- }
- callback(StringRef(buffer, bytes_count));
+
+ callback(StringRef(buffer, bytes_read));
}
});
- t.detach();
+
return Error::success();
}
+void OutputRedirector::Stop() {
+ m_stopped = true;
+
+ if (m_pipe.CanWrite()) {
+ // If the fd is waiting for input and is closed it may not return from the
+ // current select/poll/kqueue/etc. asyncio wait operation. Write a null byte
+ // to ensure the read fd wakes to detect the closed FD.
----------------
ashgti wrote:
Done
https://github.com/llvm/llvm-project/pull/120457
More information about the lldb-commits
mailing list