diff --git a/startupcache/StartupCache.cpp b/startupcache/StartupCache.cpp index cce1f77afb49..f00ff6b4228f 100644 --- a/startupcache/StartupCache.cpp +++ b/startupcache/StartupCache.cpp @@ -147,7 +147,26 @@ StartupCache::StartupCache() mPrefetchThread(nullptr) {} StartupCache::~StartupCache() { + if (mTimer) { + mTimer->Cancel(); + } + + // Generally, the in-memory table should be empty here, + // but an early shutdown means either mTimer didn't run + // or the write thread is still running. WaitOnWriteThread(); + WaitOnPrefetchThread(); + + // If we shutdown quickly timer wont have fired. Instead of writing + // it on the main thread and block the shutdown we simply wont update + // the startup cache. Always do this if the file doesn't exist since + // we use it part of the package step. + if (!mCacheData.initialized() || ShouldCompactCache()) { + mDirty = true; + auto result = WriteToDisk(); + Unused << NS_WARN_IF(result.isErr()); + } + UnregisterWeakMemoryReporter(this); } @@ -594,25 +613,6 @@ void StartupCache::InvalidateCache(bool memoryOnly) { } } -void StartupCache::MaybeInitShutdownWrite() { - if (mTimer) { - mTimer->Cancel(); - } - gShutdownInitiated = true; - - MaybeSpawnWriteThread(); - - // If we shutdown quickly timer wont have fired. Instead of writing - // it on the main thread and block the shutdown we simply wont update - // the startup cache. Always do this if the file doesn't exist since - // we use it part of the package step. - if (!mCacheData.initialized() || ShouldCompactCache()) { - mDirty = true; - auto result = WriteToDisk(); - Unused << NS_WARN_IF(result.isErr()); - } -} - void StartupCache::IgnoreDiskCache() { gIgnoreDiskCache = true; if (gStartupCache) gStartupCache->InvalidateCache(); @@ -690,28 +690,22 @@ void StartupCache::WriteTimeout(nsITimer* aTimer, void* aClosure) { * if the StartupCache object is valid. */ StartupCache* startupCacheObj = static_cast(aClosure); - startupCacheObj->MaybeSpawnWriteThread(); -} - -/* - * See StartupCache::WriteTimeout above - this is just the non-static body. - */ -void StartupCache::MaybeSpawnWriteThread() { - if (mWrittenOnce || mWriteThread) { + if (startupCacheObj->mWrittenOnce) { return; } - if (mCacheData.initialized() && !ShouldCompactCache()) { + if (startupCacheObj->mCacheData.initialized() && + !startupCacheObj->ShouldCompactCache()) { return; } - WaitOnPrefetchThread(); - mStartupWriteInitiated = false; - mDirty = true; - mCacheData.reset(); - mWriteThread = PR_CreateThread(PR_USER_THREAD, StartupCache::ThreadedWrite, - this, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, 512 * 1024); + startupCacheObj->WaitOnPrefetchThread(); + startupCacheObj->mStartupWriteInitiated = false; + startupCacheObj->mDirty = true; + startupCacheObj->mCacheData.reset(); + startupCacheObj->mWriteThread = PR_CreateThread( + PR_USER_THREAD, StartupCache::ThreadedWrite, startupCacheObj, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 512 * 1024); } // We don't want to refcount StartupCache, so we'll just @@ -726,7 +720,6 @@ nsresult StartupCacheListener::Observe(nsISupports* subject, const char* topic, if (strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { // Do not leave the thread running past xpcom shutdown sc->WaitOnWriteThread(); - sc->WaitOnPrefetchThread(); StartupCache::gShutdownInitiated = true; } else if (strcmp(topic, "startupcache-invalidate") == 0) { sc->InvalidateCache(data && nsCRT::strcmp(data, u"memoryOnly") == 0); diff --git a/startupcache/StartupCache.h b/startupcache/StartupCache.h index 2c1fca6239a5..2b10ac1a8ed9 100644 --- a/startupcache/StartupCache.h +++ b/startupcache/StartupCache.h @@ -163,10 +163,6 @@ class StartupCache : public nsIMemoryReporter { // Removes the cache file. void InvalidateCache(bool memoryOnly = false); - // For use during shutdown - this will write the startupcache's data - // to disk if the timer hasn't already gone off. - void MaybeInitShutdownWrite(); - // Signal that data should not be loaded from the cache file static void IgnoreDiskCache(); @@ -207,7 +203,6 @@ class StartupCache : public nsIMemoryReporter { void WaitOnWriteThread(); void WaitOnPrefetchThread(); void StartPrefetchMemoryThread(); - void MaybeSpawnWriteThread(); static nsresult InitSingleton(); static void WriteTimeout(nsITimer* aTimer, void* aClosure); diff --git a/xpcom/base/AppShutdown.cpp b/xpcom/base/AppShutdown.cpp index ec013608a2b7..e57392b6957e 100644 --- a/xpcom/base/AppShutdown.cpp +++ b/xpcom/base/AppShutdown.cpp @@ -16,7 +16,6 @@ #include "mozilla/CmdLineAndEnvUtils.h" #include "mozilla/PoisonIOInterposer.h" #include "mozilla/Printf.h" -#include "mozilla/scache/StartupCache.h" #include "mozilla/StartupTimeline.h" #include "mozilla/StaticPrefs_toolkit.h" #include "mozilla/LateWriteChecks.h" @@ -126,8 +125,6 @@ void AppShutdown::Init(AppShutdownMode aMode) { int32_t lateWriteChecksPref = StaticPrefs::toolkit_shutdown_lateWriteChecksStage(); sLateWriteChecksPhase = GetShutdownPhaseFromPrefValue(lateWriteChecksPref); - - scache::StartupCache::GetSingleton()->MaybeInitShutdownWrite(); } void AppShutdown::MaybeFastShutdown(ShutdownPhase aPhase) { diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp index f33fd92a8545..8be931bc8fbb 100644 --- a/xpcom/build/XPCOMInit.cpp +++ b/xpcom/build/XPCOMInit.cpp @@ -634,6 +634,7 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) { gfxPlatform::ShutdownLayersIPC(); mozilla::RemoteDecoderManagerChild::Shutdown(); + mozilla::scache::StartupCache::DeleteSingleton(); if (observerService) { mozilla::KillClearOnShutdown(ShutdownPhase::ShutdownThreads); observerService->NotifyObservers( @@ -716,8 +717,6 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) { mozilla::AppShutdown::MaybeFastShutdown( mozilla::ShutdownPhase::ShutdownPostLastCycleCollection); - mozilla::scache::StartupCache::DeleteSingleton(); - PROFILER_ADD_MARKER("Shutdown xpcom", OTHER); // Shutdown xpcom. This will release all loaders and cause others holding