Skip to content

Make run(.no_wait) collect finished I/O on IOCP - #259

Open
endel wants to merge 1 commit into
mitchellh:mainfrom
endel:iocp-no-wait
Open

endel wants to merge 1 commit into
mitchellh:mainfrom
endel:iocp-no-wait

Conversation

@endel

@endel endel commented Oct 30, 2026

Copy link
Copy Markdown

On the IOCP backend tick(0) breaks out of its loop before it calls GetQueuedCompletionStatusEx, so run(.no_wait) only runs timers and what is already queued. A completion the kernel has finished stays on the port until a blocking tick takes it.

epoll and kqueue ask the kernel once with a zero timeout. IOCP's own if (wait == 0) break; after the dequeue shows that was the intent, but as written it can't be reached with wait == 0.

We hit this running a loop from Node's libuv in quic-zig: each wakeup ran run(.no_wait), which collected nothing, so the server never saw a connection.

Fix

tick(0) now dequeues once with a zero timeout, then leaves through the existing if (wait == 0) break;. Ticks with wait > 0 are unchanged.

Test

"iocp: no_wait collects what the kernel has finished" posts a recvfrom, sends a datagram and runs no_wait until it arrives, which without the fix it never does.

  • Windows (aarch64, under Wine 10): the test passes, and fails with the fix reverted. Not run on real Windows. The process tests can't run in that container, as it lacks their helper binary.
  • macOS (aarch64, kqueue): zig build test, 59 passed
  • Linux (aarch64, epoll and io_uring): 143 passed, 3 skipped
  • zig build -Demit-example -Demit-bench, and zig build for every target in the CI matrix

CI on main fails until #250 moves the workflow to Zig 0.17, so this PR's checks will fail the same way until then.

🤖 Generated with Claude Code

tick(0) broke out of its loop before asking the completion port, so
run(.no_wait) only ran timers and what was already queued. epoll and kqueue
ask the kernel once, with a zero timeout. A host driving the loop from its
own event loop never saw a completion.

Assisted-by: Claude Opus 5.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant