[PR #16224] Fix deadlocks due to holding locks across WriteFile calls #30871

Closed
opened 2026-01-31 09:43:29 +00:00 by claunia · 0 comments
Owner

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

State: closed
Merged: Yes


This fixes a number of bugs introduced in 4370da9, all of which are of
the same kind: Holding the terminal lock across WriteFile calls into
the ConPTY pipe. This is problematic, because the pipe has a tiny buffer
size of just 4KiB and ConPTY may respond on its output pipe, before the
entire buffer given to WriteFile has been emptied. When the ConPTY
output thread then tries to acquire the terminal lock to begin parsing
the VT output, we get ourselves a proper deadlock (cross process too!).

The solution is to tease Terminal further apart into code that is
thread-safe and code that isn't. Functions like SendKeyEvent so far
have mixed them into one, because when they get called by ControlCore
they both, processed the data (not thread-safe as it accesses VT state)
and also sent that data back into ControlCore through a callback
which then indirectly called into the ConptyConnection which calls
WriteFile. Instead, we now return the data that needs to be sent from
these functions, and ControlCore is free to release the lock and
then call into the connection, which may then block indefinitely.

Validation Steps Performed

  • Start nvim in WSL
  • Press i to enter the regular Insert mode
  • Paste 1MB of text
  • Doesn't deadlock
**Original Pull Request:** https://github.com/microsoft/terminal/pull/16224 **State:** closed **Merged:** Yes --- This fixes a number of bugs introduced in 4370da9, all of which are of the same kind: Holding the terminal lock across `WriteFile` calls into the ConPTY pipe. This is problematic, because the pipe has a tiny buffer size of just 4KiB and ConPTY may respond on its output pipe, before the entire buffer given to `WriteFile` has been emptied. When the ConPTY output thread then tries to acquire the terminal lock to begin parsing the VT output, we get ourselves a proper deadlock (cross process too!). The solution is to tease `Terminal` further apart into code that is thread-safe and code that isn't. Functions like `SendKeyEvent` so far have mixed them into one, because when they get called by `ControlCore` they both, processed the data (not thread-safe as it accesses VT state) and also sent that data back into `ControlCore` through a callback which then indirectly called into the `ConptyConnection` which calls `WriteFile`. Instead, we now return the data that needs to be sent from these functions, and `ControlCore` is free to release the lock and then call into the connection, which may then block indefinitely. ## Validation Steps Performed * Start nvim in WSL * Press `i` to enter the regular Insert mode * Paste 1MB of text * Doesn't deadlock ✅
claunia added the pull-request label 2026-01-31 09:43:29 +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#30871