Bug 1437140 - Replace some uses of NS_DispatchToMainThread/NS_DispatchToCurrentThread with more specific event targets. r=mystor
authorJosh Matthews <josh@joshmatthews.net>
Tue, 20 Feb 2018 09:52:32 -0500
changeset 404534 2e14ee07de8a0dd69a9a8a2a5bb1b5cd6617f757
parent 404533 91b807639ce3ab9b02a3d5f11b9dfaea497d526a
child 404535 c755e956453d33abc78c049db0abb80b9c953c0b
push id100029
push usernbeleuzu@mozilla.com
push dateTue, 20 Feb 2018 20:13:22 +0000
treeherdermozilla-inbound@2e14ee07de8a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmystor
bugs1437140
milestone60.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 1437140 - Replace some uses of NS_DispatchToMainThread/NS_DispatchToCurrentThread with more specific event targets. r=mystor
dom/geolocation/nsGeolocation.cpp
dom/promise/Promise.cpp
dom/xml/nsXMLContentSink.cpp
gfx/src/nsThebesFontEnumerator.cpp
netwerk/base/nsInputStreamPump.cpp
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -73,16 +73,17 @@ class nsGeolocationRequest final
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGeolocationRequest, nsIContentPermissionRequest)
 
   nsGeolocationRequest(Geolocation* aLocator,
                        GeoPositionCallback aCallback,
                        GeoPositionErrorCallback aErrorCallback,
                        UniquePtr<PositionOptions>&& aOptions,
                        uint8_t aProtocolType,
+                       nsIEventTarget* aMainThreadTarget,
                        bool aWatchPositionRequest = false,
                        bool aIsHandlingUserInput = false,
                        int32_t aWatchId = 0);
 
   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsGeolocationRequest)
 
   void Shutdown();
 
@@ -131,16 +132,17 @@ class nsGeolocationRequest final
   bool mIsHandlingUserInput;
 
   RefPtr<Geolocation> mLocator;
 
   int32_t mWatchId;
   bool mShutdown;
   nsCOMPtr<nsIContentPermissionRequester> mRequester;
   uint8_t mProtocolType;
+  nsCOMPtr<nsIEventTarget> mMainThreadTarget;
 };
 
 static UniquePtr<PositionOptions>
 CreatePositionOptionsCopy(const PositionOptions& aOptions)
 {
   UniquePtr<PositionOptions> geoOptions = MakeUnique<PositionOptions>();
 
   geoOptions->mEnableHighAccuracy = aOptions.mEnableHighAccuracy;
@@ -302,28 +304,30 @@ PositionError::NotifyCallback(const GeoP
 // nsGeolocationRequest
 ////////////////////////////////////////////////////
 
 nsGeolocationRequest::nsGeolocationRequest(Geolocation* aLocator,
                                            GeoPositionCallback aCallback,
                                            GeoPositionErrorCallback aErrorCallback,
                                            UniquePtr<PositionOptions>&& aOptions,
                                            uint8_t aProtocolType,
+                                           nsIEventTarget* aMainThreadTarget,
                                            bool aWatchPositionRequest,
                                            bool aIsHandlingUserInput,
                                            int32_t aWatchId)
   : mIsWatchPositionRequest(aWatchPositionRequest),
     mCallback(Move(aCallback)),
     mErrorCallback(Move(aErrorCallback)),
     mOptions(Move(aOptions)),
     mIsHandlingUserInput(aIsHandlingUserInput),
     mLocator(aLocator),
     mWatchId(aWatchId),
     mShutdown(false),
-    mProtocolType(aProtocolType)
+    mProtocolType(aProtocolType),
+    mMainThreadTarget(aMainThreadTarget)
 {
   if (nsCOMPtr<nsPIDOMWindowInner> win =
       do_QueryReferent(mLocator->GetOwner())) {
     mRequester = new nsContentPermissionRequester(win);
   }
 }
 
 nsGeolocationRequest::~nsGeolocationRequest()
@@ -616,17 +620,17 @@ nsGeolocationRequest::GetPrincipal()
   }
   return mLocator->GetPrincipal();
 }
 
 NS_IMETHODIMP
 nsGeolocationRequest::Update(nsIDOMGeoPosition* aPosition)
 {
   nsCOMPtr<nsIRunnable> ev = new RequestSendLocationEvent(aPosition, this);
-  NS_DispatchToMainThread(ev);
+  mMainThreadTarget->Dispatch(ev.forget());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGeolocationRequest::NotifyError(uint16_t aErrorCode)
 {
   MOZ_ASSERT(NS_IsMainThread());
   RefPtr<PositionError> positionError = new PositionError(mLocator, aErrorCode);
@@ -1242,41 +1246,51 @@ Geolocation::GetCurrentPosition(Position
                                    Move(CreatePositionOptionsCopy(aOptions)),
                                    aCallerType);
 
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
   }
 }
 
+static nsIEventTarget* MainThreadTarget(Geolocation* geo)
+{
+  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(geo->GetOwner());
+  if (!window) {
+    return GetMainThreadEventTarget();
+  }
+  return nsGlobalWindowInner::Cast(window)->EventTargetFor(mozilla::TaskCategory::Other);
+}
+
 nsresult
 Geolocation::GetCurrentPosition(GeoPositionCallback callback,
                                 GeoPositionErrorCallback errorCallback,
                                 UniquePtr<PositionOptions>&& options,
                                 CallerType aCallerType)
 {
   if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // After this we hand over ownership of options to our nsGeolocationRequest.
 
   // Count the number of requests per protocol/scheme.
   Telemetry::Accumulate(Telemetry::GEOLOCATION_GETCURRENTPOSITION_SECURE_ORIGIN,
                         static_cast<uint8_t>(mProtocolType));
 
+  nsIEventTarget* target = MainThreadTarget(this);
   RefPtr<nsGeolocationRequest> request =
     new nsGeolocationRequest(this, Move(callback), Move(errorCallback),
-                             Move(options), static_cast<uint8_t>(mProtocolType),
+                             Move(options), static_cast<uint8_t>(mProtocolType), target,
                              false, EventStateManager::IsHandlingUserInput());
 
   if (!sGeoEnabled || ShouldBlockInsecureRequests() ||
       nsContentUtils::ResistFingerprinting(aCallerType)) {
     nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
-    NS_DispatchToMainThread(ev);
+    target->Dispatch(ev.forget());
     return NS_OK;
   }
 
   if (!mOwner && aCallerType != CallerType::System) {
     return NS_ERROR_FAILURE;
   }
 
   if (mOwner) {
@@ -1287,17 +1301,17 @@ Geolocation::GetCurrentPosition(GeoPosit
     return NS_OK;
   }
 
   if (aCallerType != CallerType::System) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(true, request);
-  NS_DispatchToMainThread(ev);
+  target->Dispatch(ev.forget());
 
   return NS_OK;
 }
 
 int32_t
 Geolocation::WatchPosition(PositionCallback& aCallback,
                            PositionErrorCallback* aErrorCallback,
                            const PositionOptions& aOptions,
@@ -1345,26 +1359,27 @@ Geolocation::WatchPosition(GeoPositionCa
 
   // Count the number of requests per protocol/scheme.
   Telemetry::Accumulate(Telemetry::GEOLOCATION_WATCHPOSITION_SECURE_ORIGIN,
                         static_cast<uint8_t>(mProtocolType));
 
   // The watch ID:
   *aRv = mLastWatchId++;
 
+  nsIEventTarget* target = MainThreadTarget(this);
   RefPtr<nsGeolocationRequest> request =
     new nsGeolocationRequest(this, Move(aCallback), Move(aErrorCallback),
                              Move(aOptions),
-                             static_cast<uint8_t>(mProtocolType), true,
+                             static_cast<uint8_t>(mProtocolType), target, true,
                              EventStateManager::IsHandlingUserInput(), *aRv);
 
   if (!sGeoEnabled || ShouldBlockInsecureRequests() ||
       nsContentUtils::ResistFingerprinting(aCallerType)) {
     nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
-    NS_DispatchToMainThread(ev);
+    target->Dispatch(ev.forget());
     return NS_OK;
   }
 
   if (!mOwner && aCallerType != CallerType::System) {
     return NS_ERROR_FAILURE;
   }
 
   if (mOwner) {
@@ -1448,25 +1463,26 @@ Geolocation::NotifyAllowedRequest(nsGeol
   } else {
     mPendingCallbacks.AppendElement(aRequest);
   }
 }
 
 bool
 Geolocation::RegisterRequestWithPrompt(nsGeolocationRequest* request)
 {
+  nsIEventTarget* target = MainThreadTarget(this);
   if (Preferences::GetBool("geo.prompt.testing", false)) {
     bool allow = Preferences::GetBool("geo.prompt.testing.allow", false);
     nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(allow, request);
-    NS_DispatchToMainThread(ev);
+    target->Dispatch(ev.forget());
     return true;
   }
 
   nsCOMPtr<nsIRunnable> ev  = new RequestPromptEvent(request, mOwner);
-  NS_DispatchToMainThread(ev);
+  target->Dispatch(ev.forget());
   return true;
 }
 
 JSObject*
 Geolocation::WrapObject(JSContext *aCtx, JS::Handle<JSObject*> aGivenProto)
 {
   return GeolocationBinding::Wrap(aCtx, this, aGivenProto);
 }
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -497,17 +497,22 @@ Promise::ReportRejectedPromise(JSContext
                                : GetCurrentThreadWorkerPrivate()->IsChromeWorker();
   nsGlobalWindowInner* win = isMainThread
     ? xpc::WindowGlobalOrNull(aPromise)
     : nullptr;
   xpcReport->Init(report.report(), report.toStringResult().c_str(), isChrome,
                   win ? win->AsInner()->WindowID() : 0);
 
   // Now post an event to do the real reporting async
-  NS_DispatchToMainThread(new AsyncErrorReporter(xpcReport));
+  RefPtr<nsIRunnable> event = new AsyncErrorReporter(xpcReport);
+  if (win) {
+    win->Dispatch(mozilla::TaskCategory::Other, event.forget());
+  } else {
+    NS_DispatchToMainThread(event);
+  }
 }
 
 bool
 Promise::PerformMicroTaskCheckpoint()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
 
   CycleCollectedJSContext* context = CycleCollectedJSContext::Get();
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -1610,16 +1610,16 @@ nsXMLContentSink::ContinueInterruptedPar
 void
 nsXMLContentSink::ContinueInterruptedParsingAsync()
 {
   nsCOMPtr<nsIRunnable> ev =
     NewRunnableMethod("nsXMLContentSink::ContinueInterruptedParsingIfEnabled",
                       this,
                       &nsXMLContentSink::ContinueInterruptedParsingIfEnabled);
 
-  NS_DispatchToCurrentThread(ev);
+  mDocument->Dispatch(mozilla::TaskCategory::Other, ev.forget());
 }
 
 nsIParser*
 nsXMLContentSink::GetParser()
 {
   return static_cast<nsIParser*>(mParser.get());
 }
--- a/gfx/src/nsThebesFontEnumerator.cpp
+++ b/gfx/src/nsThebesFontEnumerator.cpp
@@ -126,44 +126,47 @@ private:
     nsCOMPtr<nsIThread> mWorkerThread;
 };
 
 class EnumerateFontsTask final : public Runnable
 {
 public:
     EnumerateFontsTask(nsAtom* aLangGroupAtom,
                        const nsAutoCString& aGeneric,
-                       UniquePtr<EnumerateFontsPromise> aEnumerateFontsPromise)
+                       UniquePtr<EnumerateFontsPromise> aEnumerateFontsPromise,
+                       nsIEventTarget* aMainThreadTarget)
         : Runnable("EnumerateFontsTask")
         , mLangGroupAtom(aLangGroupAtom)
         , mGeneric(aGeneric)
         , mEnumerateFontsPromise(Move(aEnumerateFontsPromise))
+        , mMainThreadTarget(aMainThreadTarget)
     {
         MOZ_ASSERT(NS_IsMainThread());
     }
 
     NS_IMETHOD Run() override
     {
         MOZ_ASSERT(!NS_IsMainThread());
 
         nsTArray<nsString> fontList;
 
         nsresult rv = gfxPlatform::GetPlatform()->
             GetFontList(mLangGroupAtom, mGeneric, fontList);
         nsCOMPtr<nsIRunnable> runnable = new EnumerateFontsResult(
             rv, Move(mEnumerateFontsPromise), Move(fontList));
-        NS_DispatchToMainThread(runnable.forget());
+        mMainThreadTarget->Dispatch(runnable.forget());
 
         return NS_OK;
     }
 
 private:
     RefPtr<nsAtom> mLangGroupAtom;
     nsAutoCStringN<16> mGeneric;
     UniquePtr<EnumerateFontsPromise> mEnumerateFontsPromise;
+    RefPtr<nsIEventTarget> mMainThreadTarget;
 };
 
 NS_IMETHODIMP
 nsThebesFontEnumerator::EnumerateAllFontsAsync(JSContext* aCx,
                                                JS::MutableHandleValue aRval)
 {
     return EnumerateFontsAsync(nullptr, nullptr, aCx, aRval);
 }
@@ -202,18 +205,19 @@ nsThebesFontEnumerator::EnumerateFontsAs
 
     nsAutoCString generic;
     if (aGeneric) {
         generic.Assign(aGeneric);
     } else {
         generic.SetIsVoid(true);
     }
 
+    nsCOMPtr<nsIEventTarget> target = global->EventTargetFor(mozilla::TaskCategory::Other);
     nsCOMPtr<nsIRunnable> runnable = new EnumerateFontsTask(
-        langGroupAtom, generic, Move(enumerateFontsPromise));
+        langGroupAtom, generic, Move(enumerateFontsPromise), target);
     thread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL);
 
     if (!ToJSValue(aCx, promise, aRval)) {
         return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
 }
--- a/netwerk/base/nsInputStreamPump.cpp
+++ b/netwerk/base/nsInputStreamPump.cpp
@@ -665,17 +665,17 @@ nsInputStreamPump::CallOnStateStop()
 uint32_t
 nsInputStreamPump::OnStateStop()
 {
     mMutex.AssertCurrentThreadIn();
 
     if (!NS_IsMainThread()) {
         // This method can be called on a different thread if nsInputStreamPump
         // is used off the main-thread.
-        nsresult rv = NS_DispatchToMainThread(
+        nsresult rv = mLabeledMainThreadTarget->Dispatch(
           NewRunnableMethod("nsInputStreamPump::CallOnStateStop",
                             this,
                             &nsInputStreamPump::CallOnStateStop));
         NS_ENSURE_SUCCESS(rv, STATE_IDLE);
         return STATE_IDLE;
     }
 
     AUTO_PROFILER_LABEL("nsInputStreamPump::OnStateStop", NETWORK);