Skip to content

Windows: cache the stdio write mode for the duration of a lock session#159562

Open
Joel-Wwalker wants to merge 1 commit into
rust-lang:mainfrom
Joel-Wwalker:154071-stdio-handle-cache
Open

Windows: cache the stdio write mode for the duration of a lock session#159562
Joel-Wwalker wants to merge 1 commit into
rust-lang:mainfrom
Joel-Wwalker:154071-stdio-handle-cache

Conversation

@Joel-Wwalker

@Joel-Wwalker Joel-Wwalker commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

On Windows, every write to stdout/stderr calls GetStdHandle and GetConsoleMode (and GetConsoleOutputCP for consoles) to decide how to write. For bulk writes through a locked handle that is most of the work; #154071 measured 14% of CPU time in is_console alone.

This caches the handle and the console verdict in the sys-level Stdout/Stderr and re-queries when a new lock session begins, as suggested in the issue. Holding a StdoutLock pins the stream; unlocked writes acquire the lock per call, so they re-query per write exactly as before, and SetStdHandle calls made between lock sessions keep working (the #40490 behavior is preserved).

Numbers from the issue's workload shape (16 KiB chunks to NUL, 4 GiB total, Windows 11):

mode before after
stdout().lock() 0.478 s (8,561 MiB/s) 0.120 s (34,350 MiB/s)
unlocked 0.467 s 0.293 s

The unlocked case also improves because one implicit lock session can contain several sys-level writes when LineWriter splits a chunk at newlines.

The console path cannot run in CI, so it was verified under a pseudoconsole: several writes through one lock session on a CP437 console came through WriteConsoleW intact (non-ASCII included), and after SetConsoleOutputCP plus a new lock session the refresh picked up the change.

The refresh hook is a small #[cfg(windows)] shim on StdoutRaw/StderrRaw; happy to change it to a method on every platform's sys type instead if that is preferred.

Fixes #154071

Every write to stdout/stderr re-queried GetStdHandle and GetConsoleMode
(and GetConsoleOutputCP for consoles) to decide how to write, which
dominates bulk writes through a locked handle. Cache the handle and the
console verdict in the sys-level Stdout/Stderr and re-query when a new
lock session begins, so SetStdHandle calls made between lock sessions
keep working.
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 19, 2026
@rustbot

rustbot commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

r? @aapoalas

rustbot has assigned @aapoalas.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ChrisDenton, libs
  • @ChrisDenton, libs expanded to 13 candidates
  • Random selection from 7 candidates

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stdout and StdoutLock make unnecessary repeated syscalls via is_console on Windows

3 participants