Bug 1495306 - When InitOtherFamilyNames is called during stylo traversal, ensure it posts its runnable back to the main thread. r=kmag
authorJonathan Kew <jkew@mozilla.com>
Mon, 01 Oct 2018 23:38:55 +0200
changeset 494821 868e0b4673af81a6c17998ef269d76d6514b1ca3
parent 494820 6c85eac6803827b2301166dc95811f1b66df07dd
child 494822 47279941c952461a85038d1345c8aad0931c4d3f
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1495306
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1495306 - When InitOtherFamilyNames is called during stylo traversal, ensure it posts its runnable back to the main thread. r=kmag
gfx/thebes/gfxPlatformFontList.cpp
xpcom/threads/nsThreadUtils.cpp
xpcom/threads/nsThreadUtils.h
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -391,17 +391,17 @@ gfxPlatformFontList::InitOtherFamilyName
     // potential startup perf or main-thread jank.
     // (This is used so we can reliably run reftests that depend on localized
     // font-family names being available.)
     if (aDeferOtherFamilyNamesLoading &&
         Preferences::GetUint(FONT_LOADER_DELAY_PREF) > 0) {
         if (!mPendingOtherFamilyNameTask) {
             RefPtr<mozilla::CancelableRunnable> task = new InitOtherFamilyNamesRunnable();
             mPendingOtherFamilyNameTask = task;
-            NS_IdleDispatchToCurrentThread(task.forget());
+            NS_IdleDispatchToMainThread(task.forget());
         }
     } else {
         InitOtherFamilyNamesInternal(false);
     }
 }
 
 // time limit for loading facename lists (ms)
 #define NAMELIST_TIMEOUT  200
--- a/xpcom/threads/nsThreadUtils.cpp
+++ b/xpcom/threads/nsThreadUtils.cpp
@@ -320,16 +320,27 @@ NS_IdleDispatchToThread(already_AddRefed
 
 nsresult
 NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent)
 {
   return NS_IdleDispatchToThread(std::move(aEvent),
                                  NS_GetCurrentThread());
 }
 
+extern nsresult
+NS_IdleDispatchToMainThread(already_AddRefed<nsIRunnable>&& aEvent)
+{
+  nsCOMPtr<nsIThread> mainThread;
+  nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread));
+  if (NS_SUCCEEDED(rv)) {
+    return NS_IdleDispatchToThread(std::move(aEvent), mainThread);
+  }
+  return rv;
+}
+
 class IdleRunnableWrapper : public IdleRunnable
 {
 public:
   explicit IdleRunnableWrapper(already_AddRefed<nsIRunnable>&& aEvent)
     : mRunnable(std::move(aEvent))
   {
   }
 
--- a/xpcom/threads/nsThreadUtils.h
+++ b/xpcom/threads/nsThreadUtils.h
@@ -129,16 +129,29 @@ NS_DelayedDispatchToCurrentThread(
  *   If event is null.
  * @returns NS_ERROR_UNEXPECTED
  *   If the thread is shutting down.
  */
 extern nsresult
 NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent);
 
 /**
+ * Dispatch the given event to the idle queue of the main thread.
+ *
+ * @param aEvent The event to dispatch.
+ *
+ * @returns NS_ERROR_INVALID_ARG
+ *   If event is null.
+ * @returns NS_ERROR_UNEXPECTED
+ *   If the thread is shutting down.
+ */
+extern nsresult
+NS_IdleDispatchToMainThread(already_AddRefed<nsIRunnable>&& aEvent);
+
+/**
  * Dispatch the given event to the idle queue of the current thread.
  *
  * @param aEvent The event to dispatch. If the event implements
  *   nsIIdleRunnable, it will receive a call on
  *   nsIIdleRunnable::SetTimer when dispatched, with the value of
  *   aTimeout.
  *
  * @param aTimeout The time in milliseconds until the event should be