[PR #14160] [MERGED] Fix a deadlock during ConPTY shutdown #29969

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

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/14160
Author: @lhecker
Created: 10/7/2022
Status: Merged
Merged: 10/14/2022
Merged by: @undefined

Base: mainHead: dev/lhecker/14132-shutdown-deadlock


📝 Commits (4)

📊 Changes

10 files changed (+40 additions, -135 deletions)

View changed files

📝 src/host/VtInputThread.cpp (+2 -10)
📝 src/host/VtInputThread.hpp (+1 -2)
📝 src/host/VtIo.cpp (+30 -49)
📝 src/host/VtIo.hpp (+2 -3)
📝 src/interactivity/base/ServiceLocator.cpp (+0 -10)
📝 src/interactivity/inc/ServiceLocator.hpp (+1 -1)
📝 src/renderer/vt/paint.cpp (+1 -1)
📝 src/renderer/vt/state.cpp (+3 -12)
📝 src/renderer/vt/vtrenderer.hpp (+0 -1)
📝 src/winconpty/ft_pty/ConPtyTests.cpp (+0 -46)

📄 Description

Problem:

  • Calling RundownAndExit tries to flush out the last frame from VtEngine
  • VtEngine indirectly calls RundownAndExit if the pipe is gone via VtIo
  • RundownAndExit is called by other parts of OpenConsole
  • RundownAndExit must be [[noreturn]] for most parts of OpenConsole
  • VtIo itself has a mutex ensuring orderly shutdown
  • In short, doing a thread safe orderly shutdown requires us to hold both,
    a lock in RundownAndExit and VtIo at the same time, but while other parts
    need a blocking RundownAndExit, VtIo needs a non-blocking one
  • Refactoring the code to use optionally non-blocking RundownAndExit
    requires refactoring and might prove to be just as buggy

Solution:

  • Simply don't call RundownAndExit in VtEngine at all
  • In case the write pipe breaks:
    • VtEngine will close the handle
    • The client should notice that their read pipe is broken and
      close their write pipe sooner or later
    • Once we notice that our read pipe is broken, we call RundownAndExit
    • RundownAndExit might call back into VtEngine but
      without a pipe it won't do anything
  • In case the read pipe breaks or any other part calls RundownAndExit:
    • We call RundownAndExit
    • RundownAndExit might call back into VtEngine and depending on whether
      the write pipe is broken or not it will simply write into it or ignore it

Closes #14132
Pretty sure this also applies to #1810

Validation Steps Performed

  • Open 5 tabs and run MSYS2's bash --login in each of them
  • Enter-VsDevShell in another tab
  • Close window
  • 5 tab processes are killed instantly, 1 after ~3s
  • Replace conhost with OpenConsole via sfpcopy
  • Launch Dozens of Git Bash tabs in VS Code
  • Close them randomly
  • Remaining ones still work, processes are gone

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/14160 **Author:** [@lhecker](https://github.com/lhecker) **Created:** 10/7/2022 **Status:** ✅ Merged **Merged:** 10/14/2022 **Merged by:** [@undefined](undefined) **Base:** `main` ← **Head:** `dev/lhecker/14132-shutdown-deadlock` --- ### 📝 Commits (4) - [`83d14f0`](https://github.com/microsoft/terminal/commit/83d14f0dfac7965adb31509be4d860d8948d1674) Fix a deadlock during ConPTY shutdown - [`2782af5`](https://github.com/microsoft/terminal/commit/2782af5e7a2fd2c3750b2dc3575423eff5dd3934) Fix issues, address feedback - [`e1a8d06`](https://github.com/microsoft/terminal/commit/e1a8d06f2f3fdeb77866459320a7aea8b65c70c9) Remove obsolete test - [`06a56fa`](https://github.com/microsoft/terminal/commit/06a56fa552e01e2b92f303763bc820156bbba2ce) Address feedback ### 📊 Changes **10 files changed** (+40 additions, -135 deletions) <details> <summary>View changed files</summary> 📝 `src/host/VtInputThread.cpp` (+2 -10) 📝 `src/host/VtInputThread.hpp` (+1 -2) 📝 `src/host/VtIo.cpp` (+30 -49) 📝 `src/host/VtIo.hpp` (+2 -3) 📝 `src/interactivity/base/ServiceLocator.cpp` (+0 -10) 📝 `src/interactivity/inc/ServiceLocator.hpp` (+1 -1) 📝 `src/renderer/vt/paint.cpp` (+1 -1) 📝 `src/renderer/vt/state.cpp` (+3 -12) 📝 `src/renderer/vt/vtrenderer.hpp` (+0 -1) 📝 `src/winconpty/ft_pty/ConPtyTests.cpp` (+0 -46) </details> ### 📄 Description Problem: * Calling `RundownAndExit` tries to flush out the last frame from `VtEngine` * `VtEngine` indirectly calls `RundownAndExit` if the pipe is gone via `VtIo` * `RundownAndExit` is called by other parts of OpenConsole * `RundownAndExit` must be `[[noreturn]]` for most parts of OpenConsole * `VtIo` itself has a mutex ensuring orderly shutdown * In short, doing a thread safe orderly shutdown requires us to hold both, a lock in `RundownAndExit` and `VtIo` at the same time, but while other parts need a blocking `RundownAndExit`, `VtIo` needs a non-blocking one * Refactoring the code to use optionally non-blocking `RundownAndExit` requires refactoring and might prove to be just as buggy Solution: * Simply don't call `RundownAndExit` in `VtEngine` at all * In case the write pipe breaks: * `VtEngine` will close the handle * The client should notice that their read pipe is broken and close their write pipe sooner or later * Once we notice that our read pipe is broken, we call `RundownAndExit` * `RundownAndExit` might call back into `VtEngine` but without a pipe it won't do anything * In case the read pipe breaks or any other part calls `RundownAndExit`: * We call `RundownAndExit` * `RundownAndExit` might call back into `VtEngine` and depending on whether the write pipe is broken or not it will simply write into it or ignore it Closes #14132 Pretty sure this also applies to #1810 ## Validation Steps Performed * Open 5 tabs and run MSYS2's `bash --login` in each of them * `Enter-VsDevShell` in another tab * Close window * 5 tab processes are killed instantly, 1 after ~3s ✅ * Replace conhost with OpenConsole via sfpcopy * Launch Dozens of Git Bash tabs in VS Code * Close them randomly * Remaining ones still work, processes are gone ✅ --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:37:52 +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#29969