diff --git a/xpfe/appshell/src/nsWebShellWindow.cpp b/xpfe/appshell/src/nsWebShellWindow.cpp index dfe10a111581..8870259ff0b4 100644 --- a/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/xpfe/appshell/src/nsWebShellWindow.cpp @@ -92,12 +92,6 @@ nsWebShellWindow::nsWebShellWindow(PRUint32 aChromeFlags) nsWebShellWindow::~nsWebShellWindow() { - if (mWindow) { - mWindow->SetClientData(0); - mWindow->Destroy(); - mWindow = nullptr; // Force release here. - } - MutexAutoLock lock(mSPTimerLock); if (mSPTimer) mSPTimer->Cancel(); diff --git a/xpfe/appshell/src/nsWindowMediator.cpp b/xpfe/appshell/src/nsWindowMediator.cpp index c32f8a18bebd..f0a40f767992 100644 --- a/xpfe/appshell/src/nsWindowMediator.cpp +++ b/xpfe/appshell/src/nsWindowMediator.cpp @@ -757,9 +757,19 @@ nsWindowMediator::Observe(nsISupports* aSubject, const PRUnichar* aData) { if (!strcmp(aTopic, "xpcom-shutdown") && mReady) { - MutexAutoLock lock(mListLock); - while (mOldestWindow) - UnregisterWindow(mOldestWindow); + // Unregistering a window may cause its destructor to run, causing it to + // call into the window mediator, try to acquire mListLock, and deadlock. + // Our solution is to hold strong refs to all windows until we release + // mListLock. + nsTArray > windows; + + { + MutexAutoLock lock(mListLock); + while (mOldestWindow) { + windows.AppendElement(mOldestWindow->mWindow); + UnregisterWindow(mOldestWindow); + } + } mReady = false; } return NS_OK;