Bug 1189158 - shutdown font loader thread in separate event. r=m_kato a=rkent THUNDERBIRD_38_VERBRANCH
authorJohn Daggett <jdaggett@mozilla.com>
Fri, 31 Jul 2015 10:10:31 +0900
branchTHUNDERBIRD_38_VERBRANCH
changeset 261028 02840486a7a9e3580819ce0028efe0945967c258
parent 261027 c20c9e43efa67c82431e04773180d07e6c06e910
child 261029 a0390f2afafd142ad6ebf85e4d5f1aed17cff57d
push id321
push userkent@caspia.com
push dateFri, 29 Apr 2016 21:03:17 +0000
treeherdermozilla-esr38@8cc8fa60f0f6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato, rkent
bugs1189158
milestone38.8.0esrpre
Bug 1189158 - shutdown font loader thread in separate event. r=m_kato a=rkent
gfx/thebes/gfxFontInfoLoader.cpp
gfx/thebes/gfxPlatformFontList.cpp
--- a/gfx/thebes/gfxFontInfoLoader.cpp
+++ b/gfx/thebes/gfxFontInfoLoader.cpp
@@ -7,16 +7,22 @@
 #include "nsCRT.h"
 #include "nsIObserverService.h"
 #include "nsThreadUtils.h"              // for nsRunnable
 #include "gfxPlatformFontList.h"
 
 using namespace mozilla;
 using services::GetObserverService;
 
+#define LOG_FONTINIT(args) MOZ_LOG(gfxPlatform::GetLog(eGfxLog_fontinit), \
+                               LogLevel::Debug, args)
+#define LOG_FONTINIT_ENABLED() MOZ_LOG_TEST( \
+                                   gfxPlatform::GetLog(eGfxLog_fontinit), \
+                                   LogLevel::Debug)
+
 void
 FontInfoData::Load()
 {
     TimeStamp start = TimeStamp::Now();
 
     uint32_t i, n = mFontFamiliesToLoad.Length();
     mLoadStats.families = n;
     for (i = 0; i < n; i++) {
@@ -52,16 +58,31 @@ class AsyncFontInfoLoader : public nsRun
     }
 
     NS_IMETHOD Run() override;
 
     nsRefPtr<FontInfoData> mFontInfo;
     nsRefPtr<FontInfoLoadCompleteEvent> mCompleteEvent;
 };
 
+class ShutdownThreadEvent : public nsRunnable {
+    virtual ~ShutdownThreadEvent() {}
+
+    NS_DECL_ISUPPORTS_INHERITED
+
+    explicit ShutdownThreadEvent(nsIThread* aThread) : mThread(aThread) {}
+    NS_IMETHOD Run() override {
+        mThread->Shutdown();
+        return NS_OK;
+    }
+    nsCOMPtr<nsIThread> mThread;
+};
+
+NS_IMPL_ISUPPORTS_INHERITED0(ShutdownThreadEvent, nsRunnable);
+
 // runs on main thread after async font info loading is done
 nsresult
 FontInfoLoadCompleteEvent::Run()
 {
     gfxFontInfoLoader *loader =
         static_cast<gfxFontInfoLoader*>(gfxPlatformFontList::PlatformFontList());
 
     loader->FinalizeLoader(mFontInfo);
@@ -103,16 +124,19 @@ gfxFontInfoLoader::ShutdownObserver::Obs
     return NS_OK;
 }
 
 void
 gfxFontInfoLoader::StartLoader(uint32_t aDelay, uint32_t aInterval)
 {
     mInterval = aInterval;
 
+    NS_ASSERTION(!mFontInfo,
+                 "fontinfo should be null when starting font loader");
+
     // sanity check
     if (mState != stateInitial &&
         mState != stateTimerOff &&
         mState != stateTimerOnDelay) {
         CancelLoader();
     }
 
     // set up timer
@@ -146,23 +170,29 @@ gfxFontInfoLoader::StartLoader(uint32_t 
                                     nullptr);
     if (NS_FAILED(rv)) {
         return;
     }
 
     nsCOMPtr<nsIRunnable> loadEvent = new AsyncFontInfoLoader(mFontInfo);
 
     mFontLoaderThread->Dispatch(loadEvent, NS_DISPATCH_NORMAL);
+
+    if (LOG_FONTINIT_ENABLED()) {
+        LOG_FONTINIT(("(fontinit) fontloader started (fontinfo: %p)\n",
+                      mFontInfo.get()));
+    }
+
 }
 
 void
 gfxFontInfoLoader::FinalizeLoader(FontInfoData *aFontInfo)
 {
     // avoid loading data if loader has already been canceled
-    if (mState != stateAsyncLoad) {
+    if (mState != stateAsyncLoad || mFontInfo != aFontInfo) {
         return;
     }
 
     mLoadTime = mFontInfo->mLoadTime;
 
     // try to load all font data immediately
     if (LoadFontInfo()) {
         CancelLoader();
@@ -182,17 +212,17 @@ gfxFontInfoLoader::CancelLoader()
         return;
     }
     mState = stateTimerOff;
     if (mTimer) {
         mTimer->Cancel();
         mTimer = nullptr;
     }
     if (mFontLoaderThread) {
-        mFontLoaderThread->Shutdown();
+        NS_DispatchToMainThread(new ShutdownThreadEvent(mFontLoaderThread));
         mFontLoaderThread = nullptr;
     }
     RemoveShutdownObserver();
     CleanupLoader();
 }
 
 void
 gfxFontInfoLoader::LoadFontInfoTimerFire()
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -194,16 +194,20 @@ gfxPlatformFontList::~gfxPlatformFontLis
     NS_ASSERTION(gFontListPrefObserver, "There is no font list pref observer");
     Preferences::RemoveObservers(gFontListPrefObserver, kObservedPrefs);
     NS_RELEASE(gFontListPrefObserver);
 }
 
 nsresult
 gfxPlatformFontList::InitFontList()
 {
+    if (LOG_FONTINIT_ENABLED()) {
+        LOG_FONTINIT(("(fontinit) system fontlist initialization\n"));
+    }
+
     // rebuilding fontlist so clear out font/word caches
     gfxFontCache *fontCache = gfxFontCache::GetCache();
     if (fontCache) {
         fontCache->AgeAllGenerations();
         fontCache->FlushShapedWordCaches();
     }
 
     mFontFamilies.Clear();