diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index e603baaab4b1..6e63c96d7a95 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -13580,7 +13580,7 @@ #ifdef MOZ_CODE_COVERAGE value: 0 #else - value: 2 + value: 3 #endif mirror: always diff --git a/xpcom/base/AppShutdown.cpp b/xpcom/base/AppShutdown.cpp index caf62befec18..680739b73c12 100644 --- a/xpcom/base/AppShutdown.cpp +++ b/xpcom/base/AppShutdown.cpp @@ -315,7 +315,6 @@ bool AppShutdown::IsRestarting() { #ifdef DEBUG static bool sNotifyingShutdownObservers = false; -static bool sAdvancingShutdownPhase = false; bool AppShutdown::IsNoOrLegalShutdownTopic(const char* aTopic) { if (!XRE_IsParentProcess()) { @@ -333,12 +332,6 @@ void AppShutdown::AdvanceShutdownPhaseInternal( ShutdownPhase aPhase, bool doNotify, const char16_t* aNotificationData, const nsCOMPtr& aNotificationSubject) { AssertIsOnMainThread(); -#ifdef DEBUG - // Prevent us from re-entrance - MOZ_ASSERT(!sAdvancingShutdownPhase); - sAdvancingShutdownPhase = true; - auto exit = MakeScopeExit([] { sAdvancingShutdownPhase = false; }); -#endif // We ensure that we can move only forward. We cannot // MOZ_ASSERT here as there are some tests that fire @@ -347,43 +340,24 @@ void AppShutdown::AdvanceShutdownPhaseInternal( if (sCurrentShutdownPhase >= aPhase) { return; } - - nsCOMPtr thread = do_GetCurrentThread(); - if (sCurrentShutdownPhase >= ShutdownPhase::AppShutdownConfirmed) { - // Give runnables dispatched between two calls to AdvanceShutdownPhase - // a chance to run before actually advancing the phase. We must 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 of the previous phase. - // Note that this affects only 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 + // We think it would be more logical to have the following order here: + // AppShutdown::MaybeFastShutdown(aPhase); + // sTerminator->AdvancePhase(aPhase); + // obsService->NotifyObservers(...); + // mozilla::KillClearOnShutdown(aPhase); + #ifndef ANDROID if (sTerminator) { sTerminator->AdvancePhase(aPhase); } #endif - AppShutdown::MaybeFastShutdown(aPhase); - - // This will null out the gathered pointers for this phase synchronously. - // Note that we keep the old order here to avoid breakage, so be aware that - // the notifications fired below will find these already cleared in case - // you expected the opposite. mozilla::KillClearOnShutdown(aPhase); - // Empty our MT event queue to process any side effects thereof. - if (thread) { - NS_ProcessPendingEvents(thread); - } + AppShutdown::MaybeFastShutdown(aPhase); if (doNotify) { const char* aTopic = AppShutdown::GetObserverKey(aPhase); @@ -397,10 +371,6 @@ 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); - } } } } diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp index ae2ff7027c22..7ef9a98abd91 100644 --- a/xpcom/build/XPCOMInit.cpp +++ b/xpcom/build/XPCOMInit.cpp @@ -585,6 +585,7 @@ 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( @@ -594,11 +595,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 @@ -616,9 +617,11 @@ 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 inside AdvanceShutdownPhase. + // that will be processed below. 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();