Skip to content

Avoid reentrancy issues when dropping AppHost, even harder#19395

Merged
DHowett merged 1 commit intomainfrom
dev/duhowett/fix-it-again-jim
Sep 30, 2025
Merged

Avoid reentrancy issues when dropping AppHost, even harder#19395
DHowett merged 1 commit intomainfrom
dev/duhowett/fix-it-again-jim

Conversation

@DHowett
Copy link
Member

@DHowett DHowett commented Sep 29, 2025

The previous fix in #19296 moved the destruction of AppHost into the tail end after we manipulate the _windows vector; however, it kept the part which calls into XAML (Close) before the erase. I suspect that we still had some reentrancy issues, where we cached an iterator before the list was modified by another window close event.

That is:

sequenceDiagram
		Emperor->>Emperor: Close Window
		Emperor->>+AppHost: Close (a)
		AppHost->>XAML: Close
		XAML-->>Emperor: pump loop
		Emperor->>Emperor: Close Window
		Emperor->>+AppHost: Close (b)
		AppHost->>XAML: Close
		XAML-->>Emperor: pump loop
		AppHost->>-Emperor: Closed
		Emperor->>Emperor: erase(b)
		AppHost->>-Emperor: Closed
		Emperor->>Emperor: erase(a)
Loading

Moving the Close() to after the erase ensures that there are no cached iterators that survive beyond XAML pumping the message loop.

Fixes 8d41ace

The previous fix in #19296 moved the _destruction_ of AppHost into the
tail end after we manipulate the `_windows` vector; however, it kept the
part which calls into XAML (`Close`) before the `erase`. I suspect that
we still had some reentrancy issues, where we cached an iterator before
the list was modified by another window close event.

That is:

```mermaid
sequenceDiagram
		Emperor->>Emperor: Close Window
		Emperor->>+AppHost: Close (a)
		AppHost->>XAML: Close
		XAML-->>Emperor: pump loop
		Emperor->>Emperor: Close Window
		Emperor->>+AppHost: Close (b)
		AppHost->>XAML: Close
		XAML-->>Emperor: pump loop
		AppHost->>-Emperor: Closed
		Emperor->>Emperor: erase(b)
		AppHost->>-Emperor: Closed
		Emperor->>Emperor: erase(a)
```

Moving the `Close()` to after the `erase` ensures that there are no
cached iterators that survive beyond XAML pumping the message loop.

Fixes 8d41ace
Copy link
Member

@lhecker lhecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that makes sense.

@DHowett DHowett merged commit 5976de1 into main Sep 30, 2025
19 checks passed
@DHowett DHowett moved this from To Cherry Pick to Cherry Picked in 1.23 Servicing Pipeline Oct 8, 2025
@DHowett DHowett moved this from To Cherry Pick to Cherry Picked in 1.24 Servicing Pipeline Oct 8, 2025
DHowett added a commit that referenced this pull request Oct 8, 2025
The previous fix in #19296 moved the _destruction_ of AppHost into the
tail end after we manipulate the `_windows` vector; however, it kept the
part which calls into XAML (`Close`) before the `erase`. I suspect that
we still had some reentrancy issues, where we cached an iterator before
the list was modified by another window close event.

That is:

```mermaid
sequenceDiagram
		Emperor->>Emperor: Close Window
		Emperor->>+AppHost: Close (a)
		AppHost->>XAML: Close
		XAML-->>Emperor: pump loop
		Emperor->>Emperor: Close Window
		Emperor->>+AppHost: Close (b)
		AppHost->>XAML: Close
		XAML-->>Emperor: pump loop
		AppHost->>-Emperor: Closed
		Emperor->>Emperor: erase(b)
		AppHost->>-Emperor: Closed
		Emperor->>Emperor: erase(a)
```

Moving the `Close()` to after the `erase` ensures that there are no
cached iterators that survive beyond XAML pumping the message loop.

Fixes 8d41ace

(cherry picked from commit 5976de1)
Service-Card-Id: PVTI_lADOAF3p4s4AxadtzgfScoo
Service-Version: 1.23
DHowett added a commit that referenced this pull request Oct 8, 2025
The previous fix in #19296 moved the _destruction_ of AppHost into the
tail end after we manipulate the `_windows` vector; however, it kept the
part which calls into XAML (`Close`) before the `erase`. I suspect that
we still had some reentrancy issues, where we cached an iterator before
the list was modified by another window close event.

That is:

```mermaid
sequenceDiagram
		Emperor->>Emperor: Close Window
		Emperor->>+AppHost: Close (a)
		AppHost->>XAML: Close
		XAML-->>Emperor: pump loop
		Emperor->>Emperor: Close Window
		Emperor->>+AppHost: Close (b)
		AppHost->>XAML: Close
		XAML-->>Emperor: pump loop
		AppHost->>-Emperor: Closed
		Emperor->>Emperor: erase(b)
		AppHost->>-Emperor: Closed
		Emperor->>Emperor: erase(a)
```

Moving the `Close()` to after the `erase` ensures that there are no
cached iterators that survive beyond XAML pumping the message loop.

Fixes 8d41ace

(cherry picked from commit 5976de1)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgfScpM
Service-Version: 1.24
@DHowett DHowett deleted the dev/duhowett/fix-it-again-jim branch November 20, 2025 19:46
@DHowett DHowett moved this from Cherry Picked to Shipped in 1.23 Servicing Pipeline Jan 15, 2026
@DHowett DHowett moved this from Cherry Picked to Shipped in 1.24 Servicing Pipeline Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

3 participants