Skip to content

feat(fast_io): IOCP completion-port pump for batched writes (#1897)#3531

Merged
oferchen merged 2 commits into
masterfrom
feat/iocp-completion-pump-1897
May 1, 2026
Merged

feat(fast_io): IOCP completion-port pump for batched writes (#1897)#3531
oferchen merged 2 commits into
masterfrom
feat/iocp-completion-pump-1897

Conversation

@oferchen
Copy link
Copy Markdown
Owner

@oferchen oferchen commented May 1, 2026

Closes #1897.

Summary

  • Add CompletionPump in crates/fast_io/src/iocp/pump.rs: a shared
    completion-port driver that spawns a worker thread looping on
    GetQueuedCompletionStatusEx and dispatches each entry to a per-op
    CompletionHandler keyed by the address of its OVERLAPPED. This
    is the Windows analogue of an io_uring CQE drain.
  • Wire the pump module into crates/fast_io/src/iocp/mod.rs and
    re-export CompletionHandler, CompletionPump, IocpPumpConfig,
    oneshot_handler, and (Windows-only) iocp_post_completion from
    crates/fast_io/src/lib.rs.
  • Mirror the surface in crates/fast_io/src/iocp_stub.rs with
    Unsupported-returning stubs so the crate still compiles on Linux
    and macOS.
  • Clean shutdown via PostQueuedCompletionStatus with a sentinel
    completion key; Drop runs the same path so abandoned pumps still
    reap their worker thread.
  • Status interpretation: NTSTATUS read out of OVERLAPPED.Internal,
    translated to Win32 DOS errors for the most common overlapped-I/O
    outcomes (STATUS_END_OF_FILE, STATUS_CANCELLED,
    STATUS_INSUFFICIENT_RESOURCES, STATUS_IO_TIMEOUT); anything
    unrecognised passes through io::Error::from_raw_os_error.
  • All unsafe stays inside fast_io per the workspace unsafe-code
    policy. No new unsafe in transfer, core, cli, or engine.

Why this PR is foundational

#1898 (batched-write API matching the IoUringDiskBatch surface),
#1929/#1930/#1928 (concurrent IOCP paths in the receiver / disk-commit /
delta-apply hot paths), #1931/#1932 (stress tests under load), #1900
(CI matrix expansion), and #1899 (benchmark harness) all depend on
having a proactor in place. Today every IocpReader::read_at and
IocpWriter::write_at allocates a private port and inline-calls
GetQueuedCompletionStatus; the audit at
docs/audits/windows-iocp-benchmark.md (sections 1.1, 1.2, 5.1)
documents the gap. Subsequent PRs will layer batched submission on
top of this pump.

Audit findings (pre-implementation)

What is left for downstream PRs

Test plan

  • cargo fmt --all -- --check clean
  • cargo clippy -p fast_io --all-targets --all-features --no-deps -- -D warnings clean
  • cargo clippy --workspace --all-targets --all-features --no-deps -- -D warnings clean
  • cargo nextest run -p fast_io --all-features -E 'test(iocp)' (23 tests pass on macOS stub path including 3 new pump-stub tests)
  • CI: fmt+clippy, nextest (stable), Windows (stable; runs the real pump dispatch test), macOS (stable), Linux musl (stable), interop
  • Windows CI exercises pump_dispatches_overlapped_write_completion (writes via WriteFile against FILE_FLAG_OVERLAPPED handle, asserts the pump's worker fires the registered handler with the correct byte count)
  • Windows CI exercises pump_post_completion_round_trip (manual PostQueuedCompletionStatus with synthetic OVERLAPPED, asserts dispatch)

Add CompletionPump: a shared completion-port driver that owns a worker
thread looping on GetQueuedCompletionStatusEx and dispatches each
completion entry to a per-operation handler keyed by the OVERLAPPED
pointer. This is the Windows analogue of an io_uring CQE drain and is
the foundational building block for the upcoming batched-write API
(#1898), the concurrent file/socket paths (#1928-#1932), and the IOCP
benchmark harness (#1899).

Existing IocpReader/IocpWriter create a private port and inline-call
GetQueuedCompletionStatus per operation, so the pump introduces a
process-wide proactor without disturbing those single-op paths.

Cross-platform: real implementation lives behind
#[cfg(all(target_os = "windows", feature = "iocp"))]; non-Windows
targets get an Unsupported-returning stub so the crate still compiles
on Linux and macOS.

All unsafe stays inside fast_io per the workspace unsafe-code policy.
@github-actions github-actions Bot added the enhancement New feature or request label May 1, 2026
@oferchen oferchen merged commit e35209d into master May 1, 2026
41 checks passed
@oferchen oferchen deleted the feat/iocp-completion-pump-1897 branch May 1, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant