Bug 1189158 - shutdown font loader thread in separate event. r=m_kato, a=ritu
authorJohn Daggett <jdaggett@mozilla.com>
Thu, 06 Aug 2015 14:08:47 +0900
changeset 281809 3fd7b9eddf11af140496f564a537f021e4d24ea6
parent 281808 6b7f6fdb97f0873b6e860fee8f226a99ecf6a686
child 281810 9f9255fa45c0f9a1b68167913254134159f65bce
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato, ritu
bugs1189158
milestone41.0a2
Bug 1189158 - shutdown font loader thread in separate event. r=m_kato, a=ritu
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,28 @@ 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 +211,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
@@ -190,16 +190,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();