@samitouri / QOSAMI-WSL / commits / cdd8f7e5

Fix race condition causing wslc build output to be truncated (#40823)

Fix race condition causing wslc build output to be truncated (#40823) * Fix race condition causing wslc build output to be truncated * Fix IO flags * Format

Blue committed Jun 18, 2026 at 17:36 UTC cdd8f7e53640ffc4f752c9f7cdf939fe519e73d8
2 files changed +19 -26
src/windows/wslcsession/WSLCContainer.cpp
+2 -3
@@ -1103,9 +1103,8 @@ void WSLCContainerImpl::Export(WSLCHandle OutHandle) const
1103 }
1104 else
1105 {
1106 - io.AddHandle(
1107 - std::make_unique<RelayHandle<HTTPChunkBasedReadHandle>>(HandleWrapper{std::move(SocketCodePair.second)}, userHandle.Get()),
1108 - wsl::windows::common::io::MultiHandleWait::CancelOnCompleted);
1106 + io.AddHandle(std::make_unique<RelayHandle<HTTPChunkBasedReadHandle>>(
1107 + HandleWrapper{std::move(SocketCodePair.second)}, userHandle.Get()));
1108 }
1109
1110 // Release the lock so the container can still be interacted with while the export is in progress.
src/windows/wslcsession/WSLCSession.cpp
+17 -23
@@ -741,10 +741,7 @@ void WSLCSession::StreamImageOperation(DockerHTTPClient::HTTPRequestContext& req
741 }
742 };
743
744 - auto onCompleted = [&]() { io.Cancel(); };
745 -
746 - io.AddHandle(std::make_unique<DockerHTTPClient::DockerHttpResponseHandle>(
747 - requestContext, std::move(onHttpResponse), std::move(onChunk), std::move(onCompleted)));
744 + io.AddHandle(std::make_unique<DockerHTTPClient::DockerHttpResponseHandle>(requestContext, std::move(onHttpResponse), std::move(onChunk)));
745
746 io.Run({});
747
@@ -1086,10 +1083,8 @@ try
1083
1084 // With --progress=rawjson, docker writes progress to stderr and the final image ID to stdout on success (empty on
1085 // failure). Stdout is drained into allOutput (shown only on error) and its EOF signals build completion.
1089 - io.AddHandle(
1090 - std::make_unique<io::ReadHandle>(
1091 - buildProcess.GetStdHandle(1), [&](const auto& content) { allOutput.append(content.begin(), content.end()); }),
1092 - io::MultiHandleWait::CancelOnCompleted);
1086 + io.AddHandle(std::make_unique<io::ReadHandle>(
1087 + buildProcess.GetStdHandle(1), [&](const auto& content) { allOutput.append(content.begin(), content.end()); }));
1088
1089 io.AddHandle(std::make_unique<io::LineBasedReadHandle>(buildProcess.GetStdHandle(2), captureOutput, false));
1090
@@ -1289,9 +1284,7 @@ void WSLCSession::ImportImageImpl(DockerHTTPClient::HTTPRequestContext& Request,
1284 io.AddHandle(std::make_unique<io::RelayHandle<io::ReadHandle>>(
1285 common::io::HandleWrapper{userHandle.Get(), std::move(onInputComplete)}, common::io::HandleWrapper{Request.stream.native_handle()}));
1286
1292 - io.AddHandle(
1293 - std::make_unique<DockerHTTPClient::DockerHttpResponseHandle>(Request, std::move(onHttpResponse), std::move(onProgress)),
1294 - MultiHandleWait::CancelOnCompleted);
1287 + io.AddHandle(std::make_unique<DockerHTTPClient::DockerHttpResponseHandle>(Request, std::move(onHttpResponse), std::move(onProgress)));
1288
1289 io.Run({});
1290
@@ -1376,16 +1369,12 @@ void WSLCSession::SaveImageImpl(std::pair<uint32_t, wil::unique_socket>& SocketC
1369 errorJson.append(buffer.data(), buffer.size());
1370 };
1371
1379 - io.AddHandle(
1380 - std::make_unique<io::ReadHandle>(common::io::HandleWrapper{std::move(SocketCodePair.second)}, std::move(accumulateError)),
1381 - MultiHandleWait::CancelOnCompleted);
1372 + io.AddHandle(std::make_unique<io::ReadHandle>(common::io::HandleWrapper{std::move(SocketCodePair.second)}, std::move(accumulateError)));
1373 }
1374 else
1375 {
1385 - io.AddHandle(
1386 - std::make_unique<io::RelayHandle<io::HTTPChunkBasedReadHandle>>(
1387 - common::io::HandleWrapper{std::move(SocketCodePair.second)}, userHandle.Get()),
1388 - MultiHandleWait::CancelOnCompleted);
1376 + io.AddHandle(std::make_unique<io::RelayHandle<io::HTTPChunkBasedReadHandle>>(
1377 + common::io::HandleWrapper{std::move(SocketCodePair.second)}, userHandle.Get()));
1378 }
1379
1380 io.Run({});
@@ -3162,17 +3151,22 @@ MultiHandleWait WSLCSession::CreateIOContext(HANDLE CancelHandle)
3151 io::MultiHandleWait io;
3152
3153 // Cancel with E_ABORT if the session is terminating.
3165 - io.AddHandle(std::make_unique<io::EventHandle>(
3166 - m_sessionTerminatingEvent.get(), [this]() { THROW_HR_MSG(E_ABORT, "Session %lu is terminating", m_id); }));
3154 + io.AddHandle(
3155 + std::make_unique<io::EventHandle>(
3156 + m_sessionTerminatingEvent.get(), [this]() { THROW_HR_MSG(E_ABORT, "Session %lu is terminating", m_id); }),
3157 + io::MultiHandleWait::NeedNotComplete);
3158
3159 // Cancel with E_ABORT if the client process exits.
3169 - io.AddHandle(std::make_unique<io::EventHandle>(
3170 - wslutil::OpenCallingProcess(SYNCHRONIZE), [this]() { THROW_HR_MSG(E_ABORT, "Client process has exited"); }));
3160 + io.AddHandle(
3161 + std::make_unique<io::EventHandle>(
3162 + wslutil::OpenCallingProcess(SYNCHRONIZE), [this]() { THROW_HR_MSG(E_ABORT, "Client process has exited"); }),
3163 + io::MultiHandleWait::NeedNotComplete);
3164
3165 if (CancelHandle != nullptr)
3166 {
3167 io.AddHandle(
3175 - std::make_unique<io::EventHandle>(CancelHandle, []() { THROW_HR_MSG(E_ABORT, "Cancellation handle was signaled"); }));
3168 + std::make_unique<io::EventHandle>(CancelHandle, []() { THROW_HR_MSG(E_ABORT, "Cancellation handle was signaled"); }),
3169 + io::MultiHandleWait::NeedNotComplete);
3170 }
3171
3172 return io;