[PR #18816] Fix a major stdin wakeup race condition #31613

Open
opened 2026-01-31 09:48:24 +00:00 by claunia · 0 comments
Owner

Original Pull Request: https://github.com/microsoft/terminal/pull/18816

State: closed
Merged: Yes


The conhost v2 rewrite from a decade ago introduced a race condition:
Previously, we would acquire and hold the global console lock while servicing
a console API call. If the call cannot be completed a wait task is enqueued,
while the lock is held. The v2 rewrite then split the project up into a
"server" and "host" component (which remain to this day). The "host" would
hold the console lock, while the "server" was responsible for enqueueing wait
tasks outside of the console lock. Without any form of synchronization,
any operations on the waiter list would then of course introduce a race
condition. In conhost this primarily meant keyboard/mouse input, because that
runs on the separate Win32 window thread. For Windows Terminal it primarily
meant the VT input thread.

I do not know why this issue is so extremely noticeable specifically when we
respond to DSC CPR requests, but I'm also not surprised: I suspect that the
overall performance issues that conhost had for a long time, meant that most
things it did were slower than allocating the wait task.
Now that both conhost and Windows Terminal became orders of magnitudes faster
over the last few years, it probably just so happens that the DSC CPR request
takes almost exactly as many cycles to complete as allocating the wait task
does, hence perfectly reproducing the race condition.

There's also a slight chance that this is actually a regression from my ConPTY
rewrite #17510, but I fail to see what that would be. Regardless of that,
I'm 100% certain though, that this is a bug that has existed in v0.1.

Closes #18117
Closes #18800

Validation Steps Performed

  • See repro in #18800. In other words:
    • Continuously emit DSC CPR sequences
    • ...read the response from stdin
    • ...and print the response to stdout
    • Doesn't deadlock randomly anymore
  • Feature & Unit tests
**Original Pull Request:** https://github.com/microsoft/terminal/pull/18816 **State:** closed **Merged:** Yes --- The conhost v2 rewrite from a decade ago introduced a race condition: Previously, we would acquire and hold the global console lock while servicing a console API call. If the call cannot be completed a wait task is enqueued, while the lock is held. The v2 rewrite then split the project up into a "server" and "host" component (which remain to this day). The "host" would hold the console lock, while the "server" was responsible for enqueueing wait tasks _outside of the console lock_. Without any form of synchronization, any operations on the waiter list would then of course introduce a race condition. In conhost this primarily meant keyboard/mouse input, because that runs on the separate Win32 window thread. For Windows Terminal it primarily meant the VT input thread. I do not know why this issue is so extremely noticeable specifically when we respond to DSC CPR requests, but I'm also not surprised: I suspect that the overall performance issues that conhost had for a long time, meant that most things it did were slower than allocating the wait task. Now that both conhost and Windows Terminal became orders of magnitudes faster over the last few years, it probably just so happens that the DSC CPR request takes almost exactly as many cycles to complete as allocating the wait task does, hence perfectly reproducing the race condition. There's also a slight chance that this is actually a regression from my ConPTY rewrite #17510, but I fail to see what that would be. Regardless of that, I'm 100% certain though, that this is a bug that has existed in v0.1. Closes #18117 Closes #18800 ## Validation Steps Performed * See repro in #18800. In other words: * Continuously emit DSC CPR sequences * ...read the response from stdin * ...and print the response to stdout * Doesn't deadlock randomly anymore ✅ * Feature & Unit tests ✅
claunia added the pull-request label 2026-01-31 09:48:24 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#31613