Remove the window thread from the list of threads before nulling the AppHost (#15231)

See
https://github.com/microsoft/terminal/issues/14957#issuecomment-1520522722.

I think there's a race here that lets the WindowEmperor muck around with
the window after it's done, but before we remove it from our list of
threads.

This _should_ remove the thread from the list, _then_ null out the
AppHost, then flush the XAML queue, preventing the A/V.

Closes MSFT:43995981
This commit is contained in:
Mike Griese
2023-04-25 09:43:51 -05:00
committed by GitHub
parent 0d1540bbd2
commit e491141bd9
3 changed files with 16 additions and 3 deletions

View File

@@ -140,7 +140,7 @@ void WindowEmperor::_createNewWindowThread(const Remoting::WindowRequestedArgs&
std::thread t([weakThis, window]() {
try
{
const auto cleanup = wil::scope_exit([&]() {
auto cleanup = wil::scope_exit([&]() {
if (auto self{ weakThis.lock() })
{
self->_windowExitedHandler(window->Peasant().GetID());
@@ -155,6 +155,16 @@ void WindowEmperor::_createNewWindowThread(const Remoting::WindowRequestedArgs&
}
window->RunMessagePump();
// Manually trigger the cleanup callback. This will ensure that we
// remove the window from our list of windows, before we release the
// AppHost (and subsequently, the host's Logic() member that we use
// elsewhere).
cleanup.reset();
// Now that we no longer care about this thread's window, let it
// release it's app host and flush the rest of the XAML queue.
window->RundownForExit();
}
CATCH_LOG()
});

View File

@@ -37,7 +37,11 @@ int WindowThread::RunMessagePump()
// Enter the main window loop.
const auto exitCode = _messagePump();
// Here, the main window loop has exited.
return exitCode;
}
void WindowThread::RundownForExit()
{
_host = nullptr;
// !! LOAD BEARING !!
//
@@ -54,8 +58,6 @@ int WindowThread::RunMessagePump()
::DispatchMessageW(&msg);
}
}
return exitCode;
}
winrt::TerminalApp::TerminalWindow WindowThread::Logic()

View File

@@ -15,6 +15,7 @@ public:
winrt::TerminalApp::TerminalWindow Logic();
void CreateHost();
int RunMessagePump();
void RundownForExit();
winrt::Microsoft::Terminal::Remoting::Peasant Peasant();