================
@@ -31,6 +34,122 @@ static DWORD 
ToTimeout(std::optional<MainLoopWindows::TimePoint> point) {
   return ceil<milliseconds>(dur).count();
 }
 
+namespace {
+
+class PipeEvent : public MainLoopWindows::IOEvent {
+public:
+  explicit PipeEvent(HANDLE handle)
+      : IOEvent((IOObject::WaitableHandle)CreateEventW(
+            NULL, /*bManualReset=*/FALSE,
+            /*bInitialState=*/FALSE, NULL)),
+        m_handle(handle), m_ready(CreateEventW(NULL, /*bManualReset=*/FALSE,
+                                               /*bInitialState=*/FALSE, NULL)) 
{
+    assert(m_event && m_ready);
+  }
+
+  ~PipeEvent() override {
+    if (m_monitor_thread.joinable()) {
+      m_stopped = true;
+      SetEvent(m_ready);
+      // Keep trying to cancel ReadFile() until the thread exits.
+      do {
+        CancelIoEx((HANDLE)m_handle, /*lpOverlapped=*/NULL);
+      } while (WaitForSingleObject(m_monitor_thread.native_handle(), 1) ==
+               WAIT_TIMEOUT);
+      m_monitor_thread.join();
+    }
+    CloseHandle((HANDLE)m_event);
+    CloseHandle(m_ready);
+  }
+
+  void WillPoll() override {
+    if (!m_monitor_thread.joinable())
+      m_monitor_thread = std::thread(&PipeEvent::Monitor, this);
+  }
+
+  void Disarm() override { SetEvent(m_ready); }
+
+  /// Monitors the handle performing a zero byte read to determine when data is
+  /// avaiable.
+  void Monitor() {
+    do {
+      char buf[1];
+      DWORD bytes_read = 0;
+      OVERLAPPED ov = {0};
+      // Block on a 0-byte read; this will only resume when data is
+      // available in the pipe. The pipe must be PIPE_WAIT or this thread
+      // will spin.
+      BOOL success =
+          ReadFile(m_handle, buf, /*nNumberOfBytesToRead=*/0, &bytes_read, 
&ov);
+      DWORD bytes_available = 0;
+      DWORD err = GetLastError();
----------------
slydiman wrote:

Don't call GetLastError() if ReadFile returned TRUE! 

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

Reply via email to