[PR #15335] [MERGED] Avoid async infinite loop on tab close #30600

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

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/15335
Author: @lhecker
Created: 5/12/2023
Status: Merged
Merged: 8/15/2023
Merged by: @zadjii-msft

Base: mainHead: dev/lhecker/pane-infinite-loop


📝 Commits (4)

  • cdc0339 Avoid async infinite loop on tab close
  • 26e7e0d Bring in the remaining Pane changes
  • a9e62f5 Merge remote-tracking branch 'origin/main' into dev/lhecker/pane-infinite-loop
  • f04f1c5 Merge remote-tracking branch 'origin/main' into dev/lhecker/pane-infinite-loop

📊 Changes

6 files changed (+151 additions, -168 deletions)

View changed files

📝 src/cascadia/TerminalApp/Pane.cpp (+132 -144)
📝 src/cascadia/TerminalApp/Pane.h (+2 -4)
📝 src/cascadia/TerminalApp/TabBase.cpp (+0 -1)
📝 src/cascadia/TerminalApp/TabManagement.cpp (+11 -3)
📝 src/cascadia/TerminalApp/TerminalPage.cpp (+6 -14)
📝 src/cascadia/TerminalApp/TerminalPage.h (+0 -2)

📄 Description

When a tab gets closed, _RemoveTab will call TabBase::Shutdown(),
which then re-raises the Closed event, which will end up calling
_RemoveTab again, etc. The only reason this didn't crash WT so far
is because _RemoveOnCloseRoutine contains a resume_foreground,
which would resolve the recursion and turn it into CPU usage.
It would spin as long as WinUI hasn't discard the tab object,
which takes an unpredictable amount of time.

Raising the Closed event from Shutdown() is unnecessary, because
the handlers of the event end up calling _RemoveTab anyways.
Technically the entire Closed event can be removed now, but I left it
in anyways because resolving the architectural "knot" around the way
tab closing after the last pane closes is implemented requires much
more significant changes.

This commit additionally removes the _createCloseLock mutex in Pane
as it was very likely not working as intended anyways. Only some methods
were protected by it and it doesn't avoid any STA/MTA/NA issues either.

Validation Steps Performed

  • Closing tabs and panes always ends up calling Shutdown()

Closes #14898


🔄 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/15335 **Author:** [@lhecker](https://github.com/lhecker) **Created:** 5/12/2023 **Status:** ✅ Merged **Merged:** 8/15/2023 **Merged by:** [@zadjii-msft](https://github.com/zadjii-msft) **Base:** `main` ← **Head:** `dev/lhecker/pane-infinite-loop` --- ### 📝 Commits (4) - [`cdc0339`](https://github.com/microsoft/terminal/commit/cdc03393bfcf10021f4b38cd76d762f7c3bdf517) Avoid async infinite loop on tab close - [`26e7e0d`](https://github.com/microsoft/terminal/commit/26e7e0dea106490ed8dca3b5ad9d89aa0559c038) Bring in the remaining Pane changes - [`a9e62f5`](https://github.com/microsoft/terminal/commit/a9e62f509461d2ba0d7f92e399ecc37206b3d3e1) Merge remote-tracking branch 'origin/main' into dev/lhecker/pane-infinite-loop - [`f04f1c5`](https://github.com/microsoft/terminal/commit/f04f1c598fbec515dea3a3a6f72edba4bde857ae) Merge remote-tracking branch 'origin/main' into dev/lhecker/pane-infinite-loop ### 📊 Changes **6 files changed** (+151 additions, -168 deletions) <details> <summary>View changed files</summary> 📝 `src/cascadia/TerminalApp/Pane.cpp` (+132 -144) 📝 `src/cascadia/TerminalApp/Pane.h` (+2 -4) 📝 `src/cascadia/TerminalApp/TabBase.cpp` (+0 -1) 📝 `src/cascadia/TerminalApp/TabManagement.cpp` (+11 -3) 📝 `src/cascadia/TerminalApp/TerminalPage.cpp` (+6 -14) 📝 `src/cascadia/TerminalApp/TerminalPage.h` (+0 -2) </details> ### 📄 Description When a tab gets closed, `_RemoveTab` will call `TabBase::Shutdown()`, which then re-raises the `Closed` event, which will end up calling `_RemoveTab` again, etc. The only reason this didn't crash WT so far is because `_RemoveOnCloseRoutine` contains a `resume_foreground`, which would resolve the recursion and turn it into CPU usage. It would spin as long as WinUI hasn't discard the tab object, which takes an unpredictable amount of time. Raising the `Closed` event from `Shutdown()` is unnecessary, because the handlers of the event end up calling `_RemoveTab` anyways. Technically the entire `Closed` event can be removed now, but I left it in anyways because resolving the architectural "knot" around the way tab closing after the last pane closes is implemented requires much more significant changes. This commit additionally removes the `_createCloseLock` mutex in `Pane` as it was very likely not working as intended anyways. Only some methods were protected by it and it doesn't avoid any STA/MTA/NA issues either. ## Validation Steps Performed * Closing tabs and panes always ends up calling `Shutdown()` ✅ Closes #14898 --- <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:41:48 +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#30600