Localhost Relay: non-blocking IO on Linux side, IOCP with fully async reads and writes on Windows side#40171
Localhost Relay: non-blocking IO on Linux side, IOCP with fully async reads and writes on Windows side#40171
Conversation
… reads and writes on Windows side
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Refactors the localhost relay implementation to use non-blocking, back-pressure-aware I/O on Linux and IOCP-based fully asynchronous I/O on Windows, improving full-duplex throughput and correct half-close behavior.
Changes:
- Windows: replaced wait/event-based overlapped I/O with IOCP dispatch and per-direction read/write state machines.
- Linux: switched sockets to non-blocking mode and implemented a poll-driven relay with per-direction buffering and compaction.
- Added per-direction half-close handling so each direction can complete independently.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/windows/common/relay.cpp | Reworks BidirectionalRelay to use IOCP with per-direction async read/write contexts and completion processing. |
| src/linux/init/localhost.cpp | Implements a non-blocking poll() relay loop with per-direction buffers, back-pressure, and half-close support. |
|
“Thanks for the notification. Update received.”
获取 Outlook for iOS<https://aka.ms/o0ukef>
________________________________
发件人: wangxin12 ***@***.***>
发送时间: Tuesday, April 14, 2026 5:43:42 AM
收件人: microsoft/WSL ***@***.***>
抄送: Subscribed ***@***.***>
主题: Re: [microsoft/WSL] Localhost Relay: non-blocking IO on Linux side, IOCP with fully async reads and writes on Windows side (PR #40171)
@wangxin12 commented on this pull request.
________________________________
In src/linux/init/localhost.cpp<#40171 (comment)>:
+ if (pfds[j].events & POLLOUT)
{
- bytesRead = UtilReadBuffer(pollDescriptors[Index].fd, buffer);
- if (bytesRead == 0)
+ // can't write to dstFd any more
+ if (pfds[j].revents & (POLLERR | POLLHUP))
{
- pollDescriptors[Index].fd = -1;
- shutdown(outFd[Index], SHUT_WR);
+ d.done = true;
+ continue;
}
- else if (bytesRead < 0)
+
+ if (!(pfds[j].revents & POLLOUT))
{
- return;
+ continue;
+ }
Both fds are owned by unique_fd and are never closed during the relay loop, so POLLNVAL cannot occur.
―
Reply to this email directly, view it on GitHub<#40171 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/B677FUKLYOJS6P74H5GV4N34VVNQZAVCNFSM6AAAAACXXZYSQCVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHM2DCMBSGEYTOMJXGM>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
| continue; | ||
| } | ||
|
|
||
| d.Compact(); |
There was a problem hiding this comment.
Could simplify the logic to wait for the buffer to be empty before accepting any reads. This shouldn't be a huge performance penalty as there is already a read buffer in the kernel.
| else | ||
| { | ||
| return; | ||
| d.tail += nread; |
There was a problem hiding this comment.
Should do a write here. There is no need to set the write handler most of the time.
|
|
||
| const auto bufferSize = message->BufferSize; | ||
| buffer.resize(bufferSize); | ||
| RelayDirection dirs[2] = { |
There was a problem hiding this comment.
nit: Consider use directions and direction instead of dir and d?
| if (!d.done && d.srcEof && d.Pending() == 0) | ||
| { | ||
| shutdown(d.dstFd, SHUT_WR); | ||
| d.done = true; |
There was a problem hiding this comment.
Instead of labeling this as done. Consider remove this direction from the array to release resources.
| continue; | ||
| } | ||
|
|
||
| d.done = true; |
There was a problem hiding this comment.
Should half close the read end?
| { | ||
| if (!d.done && d.srcEof && d.Pending() == 0) | ||
| { | ||
| shutdown(d.dstFd, SHUT_WR); |
There was a problem hiding this comment.
Could put half close of both the read and write end in the destructor. Then there is no need to do this complex state tracking.
|
@guanwenbin123 Hi, could you please configure your auto reply so it does not create a message for every wsl update? Thanks. |
Summary of the Pull Request
Linux — non-blocking poll-based state machine:
Windows — IOCP with fully async reads and writes:
Testing
Without the change, the test tool hangs.
PR Checklist
Detailed Description of the Pull Request / Additional comments
Validation Steps Performed