Migrate GuestTelemetryLogger to MultiHandleWait IO infrastructure (#40730)

Replace the manual for(;;) InterruptableRead loop with the io::MultiHandleWait/ReadHandle/EventHandle model already used by the console relay, so guest telemetry reads share the unified overlapped-IO wait path. Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Ben Hillis committed Jun 17, 2026 at 18:55 UTC 28447f5f061bf1e0218bb8cf701067098a7721b1
1 file changed +22 -17
src/windows/service/exe/GuestTelemetryLogger.cpp
+22 -17
@@ -61,23 +61,28 @@ void GuestTelemetryLogger::Start(const wil::unique_event& ExitEvent)
61 const std::vector<HANDLE> exitEvents = {m_threadExit.get(), ExitEvent.get()};
62 wsl::windows::common::helpers::ConnectPipe(Pipe.get(), INFINITE, exitEvents);
63
64 - std::vector<gsl::byte> buffer(LX_RELAY_BUFFER_SIZE);
65 - OVERLAPPED overlapped = {};
66 - const wil::unique_event overlappedEvent(wil::EventOptions::ManualReset);
67 - overlapped.hEvent = overlappedEvent.get();
68 - for (;;)
69 - {
70 - overlappedEvent.ResetEvent();
71 - const auto bytesRead =
72 - wsl::windows::common::relay::InterruptableRead(Pipe.get(), gsl::make_span(buffer), exitEvents, &overlapped);
73 -
74 - if (bytesRead == 0)
75 - {
76 - break;
77 - }
78 -
79 - ProcessInput(std::string_view{reinterpret_cast<const char*>(buffer.data()), bytesRead});
80 - }
64 + namespace io = wsl::windows::common::io;
65 + io::MultiHandleWait ioWait;
66 + ioWait.AddHandle(
67 + std::make_unique<io::ReadHandle>(
68 + io::HandleWrapper{Pipe.get()},
69 + [this](const gsl::span<char>& buffer) {
70 + if (!buffer.empty())
71 + {
72 + ProcessInput(std::string_view{buffer.data(), static_cast<size_t>(buffer.size())});
73 + }
74 + }),
75 + io::MultiHandleWait::IgnoreErrors);
76 +
77 + ioWait.AddHandle(
78 + std::make_unique<io::EventHandle>(io::HandleWrapper{m_threadExit.get()}),
79 + io::MultiHandleWait::CancelOnCompleted | io::MultiHandleWait::NeedNotComplete);
80 +
81 + ioWait.AddHandle(
82 + std::make_unique<io::EventHandle>(io::HandleWrapper{ExitEvent.get()}),
83 + io::MultiHandleWait::CancelOnCompleted | io::MultiHandleWait::NeedNotComplete);
84 +
85 + ioWait.Run(std::nullopt);
86 }
87 CATCH_LOG()
88 });