[PR #14282] Wait for clients to exit on ConPTY shutdown #30044

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

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

State: closed
Merged: Yes


#14160 didn't fix #14132 entirely. There seems to be a race condition left
where (on my system) 9 out of 10 times everything works correctly,
but sometimes OpenConsole exits, while pwsh and bash keep running.

My leading theory is that the new code is exiting OpenConsole faster than the
old code. This prevents clients from calling console APIs, etc. causing them
to get stuck. The old code (and new code) calls ExitProcess when the ConPTY
pipes break and I think this is wrong: In conhost when you close the window we
only call CloseConsoleProcessState via the WM_CLOSE event and that's it.
Solution: Remove the call to RundownAndExit for ConPTY.

During testing I found that continuously printing text inside msys2 will cause
child processes to only exit slowly one by one every 5 seconds.
This happens because CloseConsoleProcessState calls HandleCtrlEvent without
holding the console lock. This creates a race condition where most of the time
the console IO thread is the one picking up the CTRL_CLOSE_EVENT. But that's
problematic because the CTRL_CLOSE_EVENT leads to a ConsoleControl call of
type ConsoleEndTask which calls back into conhost's IO thread and
so you got the IO thread waiting on itself to respond.
Solution: Don't race conditions.

Validation Steps Performed

  • Enter-VsDevShell and close the tab
    Everything exits after 5s ✅
  • Run msys2 bash from within pwsh and close the tab
    Everything exits instantly ✅
  • Run cat bigfile.txt and close the tab
    Everything exits instantly ✅
  • Patch conhost.exe with sfpcopy, as well as KernelBase.dll
    with the recent changes to winconpty, then launch and exit
    shells and applications via VS Code's terminal ✅
  • On the main branch without this modification remove the call to
    TriggerTeardown in RundownAndExit (this speeds up the shutdown).
    Run (msys2's) bash.exe --login and hold enter and then press Ctrl+Shift+W
    simultaneously. The tab should close and randomly OpenConsole should exit
    early while pwsh/bash keep running. Then retry this with this branch and
    observe how the child processes don't stick around forever anymore. ✅
**Original Pull Request:** https://github.com/microsoft/terminal/pull/14282 **State:** closed **Merged:** Yes --- #14160 didn't fix #14132 entirely. There seems to be a race condition left where (on my system) 9 out of 10 times everything works correctly, but sometimes OpenConsole exits, while pwsh and bash keep running. My leading theory is that the new code is exiting OpenConsole faster than the old code. This prevents clients from calling console APIs, etc. causing them to get stuck. The old code (and new code) calls `ExitProcess` when the ConPTY pipes break and I think this is wrong: In conhost when you close the window we only call `CloseConsoleProcessState` via the `WM_CLOSE` event and that's it. Solution: Remove the call to `RundownAndExit` for ConPTY. During testing I found that continuously printing text inside msys2 will cause child processes to only exit slowly one by one every 5 seconds. This happens because `CloseConsoleProcessState` calls `HandleCtrlEvent` without holding the console lock. This creates a race condition where most of the time the console IO thread is the one picking up the `CTRL_CLOSE_EVENT`. But that's problematic because the `CTRL_CLOSE_EVENT` leads to a `ConsoleControl` call of type `ConsoleEndTask` which calls back into conhost's IO thread and so you got the IO thread waiting on itself to respond. Solution: Don't race conditions. ## Validation Steps Performed * `Enter-VsDevShell` and close the tab Everything exits after 5s ✅ * Run msys2 bash from within pwsh and close the tab Everything exits instantly ✅ * Run `cat bigfile.txt` and close the tab Everything exits instantly ✅ * Patch `conhost.exe` with `sfpcopy`, as well as `KernelBase.dll` with the recent changes to `winconpty`, then launch and exit shells and applications via VS Code's terminal ✅ * On the main branch without this modification remove the call to `TriggerTeardown` in `RundownAndExit` (this speeds up the shutdown). Run (msys2's) `bash.exe --login` and hold enter and then press Ctrl+Shift+W simultaneously. The tab should close and randomly OpenConsole should exit early while pwsh/bash keep running. Then retry this with this branch and observe how the child processes don't stick around forever anymore. ✅
claunia added the pull-request label 2026-01-31 09:38:19 +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#30044