[PR #15424] Refrigerate our threads for later reuse #30635

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

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

State: closed
Merged: Yes


This is my proposed solution to #15384.

Basically, the issue is that we cannot ever close a DesktopWindowXamlSource ("DWXS"). If we do, then any other thread that tries to access XAML metadata will explode, which happens frequently. A DWXS is inextricably linked to an HWND. That means we have to not only reuse DWXS's, but the HWNDs themselves. XAML also isn't agile, so we've got to keep the thread that the DWXS was started on alive as well.

To do this, we're going to introduce the ability to "refrigerate" and "reheat" window threads.

  • A window thread is "hot" if it's actively got a window, and is pumping window messages, and generally, is a normal thing.
  • When a window is closed, we need to "refrigerate" it's WindowThread and IslandWindow. WindowEmperor will take care of tracking the threads that are refrigerated.
  • When a new window is requested, the Emperor first try to "reheat"/"microwave" a refrigerated thread. When a thread gets reheated, we'll create a new AppHost (and TerminalWindow/Page), and we'll use the existing IslandWindow for that instance.

The metaphor is obviously ridiculous, but you get it so who cares.

In this way, we'll keep all the windows we've ever created around in memory, for later reuse. This means that the leak goes from (~12MB x number of windows closed) to (~12MB x maximum number of simultaneously open Terminal windows). It's still not good.

We won't do this on Windows 11, because the bug that is the fundamental premise of this issue is fixed already in the OS.

I'm not 100% confident in this yet.

  • There's still a d3d leak of some sort on exit in debug builds. (maybe #15306 related)
    • havent seen this in a while. Must have been a issue in an earlier revision.
  • I need to validate more on Windows 11
    • BAD: Closing the last tab on Windows 11 doesn't close the window
    • BAD: Closing a window on Windows 11 doesn't close the window - it just closes the one tab item and keeps on choochin'
    • BAD: Close last tab, open new one, attempt to close window - ALL windows go *poof*. Cause of course. No break into post-mortem either.
  • more comments
  • maybe a diagram
  • Restoring windows is at the wrong place entirely? I once reopened the Terminal with two persisted windows, and it created one at 0,0
  • Remaining code TODO!s: 0 (?)
  • "warm-reloading" useTabsInTitlebar (change while terminal is running after closing a window, open a new one) REALLY doesn't work. Obviously restores the last kind of window. Yike.

is all about #15384

closes #15410 along the way. Might fork that fix off.

**Original Pull Request:** https://github.com/microsoft/terminal/pull/15424 **State:** closed **Merged:** Yes --- This is my proposed solution to #15384. Basically, the issue is that we cannot ever close a `DesktopWindowXamlSource` ("DWXS"). If we do, then any other thread that tries to access XAML metadata will explode, which happens frequently. A DWXS is inextricably linked to an HWND. That means we have to not only reuse DWXS's, but the HWNDs themselves. XAML also isn't agile, so we've got to keep the `thread` that the DWXS was started on alive as well. To do this, we're going to introduce the ability to "refrigerate" and "reheat" window threads. * A window thread is "**hot**" if it's actively got a window, and is pumping window messages, and generally, is a normal thing. * When a window is closed, we need to "**refrigerate**" it's `WindowThread` and `IslandWindow`. `WindowEmperor` will take care of tracking the threads that are refrigerated. * When a new window is requested, the Emperor first try to "**reheat**"/"**microwave**" a refrigerated thread. When a thread gets reheated, we'll create a new AppHost (and `TerminalWindow`/`Page`), and we'll use the _existing_ `IslandWindow` for that instance. <sub>The metaphor is obviously ridiculous, but _you get it_ so who cares.</sub> In this way, we'll keep all the windows we've ever created around in memory, for later reuse. This means that the leak goes from (~12MB x number of windows closed) to (~12MB x maximum number of simultaneously open Terminal windows). It's still not good. We won't do this on Windows 11, because the bug that is the fundamental premise of this issue is fixed already in the OS. I'm not 100% confident in this yet. * [x] There's still a d3d leak of some sort on exit in debug builds. (maybe #15306 related) * havent seen this in a while. Must have been a issue in an earlier revision. * [x] I need to validate more on Windows 11 * [x] **BAD**: Closing the last tab on Windows 11 doesn't close the window * [x] **BAD**: Closing a window on Windows 11 doesn't close the window - it just closes the one tab item and keeps on choochin' * [x] **BAD**: Close last tab, open new one, attempt to close window - ALL windows go \*poof\*. Cause of course. No break into post-mortem either. * [x] more comments * [ ] maybe a diagram * [x] Restoring windows is at the wrong place entirely? I once reopened the Terminal with two persisted windows, and it created one at 0,0 * [x] Remaining code TODO!s: 0 (?) * [ ] "warm-reloading" `useTabsInTitlebar` (change while terminal is running after closing a window, open a new one) REALLY doesn't work. Obviously restores the last kind of window. Yike. is all about #15384 closes #15410 along the way. Might fork that fix off.
claunia added the pull-request label 2026-01-31 09:41:59 +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#30635