Bug 1709184 - Part 1: Process pending MT events before advancing the shutdown phase. r=xpcom-reviewers,nika,kmag

Differential Revision: https://phabricator.services.mozilla.com/D160176
This commit is contained in:
Jens Stutte 2022-12-12 15:21:26 +00:00
parent cea6eec9e0
commit 1a706a942e
2 changed files with 23 additions and 5 deletions

View File

@ -340,6 +340,23 @@ void AppShutdown::AdvanceShutdownPhaseInternal(
if (sCurrentShutdownPhase >= aPhase) {
return;
}
nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
if (sCurrentShutdownPhase >= ShutdownPhase::AppShutdownConfirmed) {
// Give runnables dispatched so far as part of the ongoing phase a chance
// to run before actually advancing the phase. We can do this only after
// we passed the point of no return and thus can expect a linear flow
// through our shutdown phases. This way the processing is also covered
// by the terminator's timer.
// Note that this happens only for main thread runnables, such that the
// correct way of ensuring shutdown processing remains to have an async
// shutdown blocker.
if (thread) {
NS_ProcessPendingEvents(thread);
}
}
// From now on any IsInOrBeyond checks will find the new phase set.
sCurrentShutdownPhase = aPhase;
// TODO: Bug 1768581
@ -371,6 +388,10 @@ void AppShutdown::AdvanceShutdownPhaseInternal(
#endif
obsService->NotifyObservers(aNotificationSubject, aTopic,
aNotificationData);
// Empty our MT event queue again after the notification has finished
if (thread) {
NS_ProcessPendingEvents(thread);
}
}
}
}

View File

@ -585,7 +585,6 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) {
// This must happen after the shutdown of media and widgets, which
// are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
NS_ProcessPendingEvents(thread);
gfxPlatform::ShutdownLayersIPC();
mozilla::AppShutdown::AdvanceShutdownPhase(
@ -595,11 +594,11 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) {
// dispatches to non main-thread threads.
ThreadEventTarget::XPCOMShutdownThreadsNotificationFinished();
#endif
NS_ProcessPendingEvents(thread);
// Shutdown the timer thread and all timers that might still be alive
nsTimerImpl::Shutdown();
// Have an extra round of processing after the timers went away.
NS_ProcessPendingEvents(thread);
// Shutdown all remaining threads. This method does not return until
@ -617,11 +616,9 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) {
// XPCOMShutdownFinal is the default phase for ClearOnShutdown.
// This AdvanceShutdownPhase will thus free most ClearOnShutdown()'ed
// smart pointers. Some destructors may fire extra main thread runnables
// that will be processed below.
// that will be processed inside AdvanceShutdownPhase.
AppShutdown::AdvanceShutdownPhase(ShutdownPhase::XPCOMShutdownFinal);
NS_ProcessPendingEvents(thread);
// Shutdown the main thread, processing our last round of events, and then
// mark that we've finished main thread event processing.
nsThreadManager::get().ShutdownMainThread();