Bug 1330185 - Allow notifying observers for profiler state changes on background threads. r?njn draft
authorMarkus Stange <mstange@themasta.com>
Mon, 15 May 2017 19:43:08 -0400
changeset 578159 c36efcbef87da4a08d39015113d9be15ca4d2ff9
parent 578158 f832d9fda068c6697413ddf2adb53284f95a36cf
child 578160 b37a069f01c934a8a3b4e449fb57cdcc6ae25266
push id58914
push userbmo:mstange@themasta.com
push dateMon, 15 May 2017 23:47:16 +0000
reviewersnjn
bugs1330185
milestone55.0a1
Bug 1330185 - Allow notifying observers for profiler state changes on background threads. r?njn If NotifyObservers is called on a background thread, dispatch a runnable to the main thread which will send the observer notification. MozReview-Commit-ID: GlkVwGTa2b4
tools/profiler/core/platform.cpp
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -501,29 +501,16 @@ private:
   static MOZ_THREAD_LOCAL(ThreadInfo*) sThreadInfo;
 };
 
 MOZ_THREAD_LOCAL(ThreadInfo*) TLSInfo::sThreadInfo;
 
 // The name of the main thread.
 static const char* const kMainThreadName = "GeckoMain";
 
-static bool
-CanNotifyObservers()
-{
-  MOZ_RELEASE_ASSERT(NS_IsMainThread());
-
-#if defined(GP_OS_android)
-  // Android ANR reporter uses the profiler off the main thread.
-  return NS_IsMainThread();
-#else
-  return true;
-#endif
-}
-
 ////////////////////////////////////////////////////////////////////////
 // BEGIN tick/unwinding code
 
 // TickSample contains all the information needed by Tick(). Some of it is
 // pointers to long-lived things, and some of it is sampled just before the
 // call to Tick().
 class TickSample {
 public:
@@ -1955,52 +1942,42 @@ locked_register_thread(PSLockRef aLock, 
       info->PollJSSampling();
     }
   }
 
   CorePS::LiveThreads(aLock).push_back(info);
 }
 
 static void
+NotifyObservers(const char* aTopic, nsISupports* aSubject = nullptr)
+{
+  if (!NS_IsMainThread()) {
+    nsCOMPtr<nsISupports> subject = aSubject;
+    NS_DispatchToMainThread(NS_NewRunnableFunction([=] { NotifyObservers(aTopic, subject); }));
+    return;
+  }
+
+  if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) {
+    os->NotifyObservers(aSubject, aTopic, nullptr);
+  }
+}
+
+static void
 NotifyProfilerStarted(const int aEntries, double aInterval, uint32_t aFeatures,
                       const char** aFilters, uint32_t aFilterCount)
 {
-  if (!CanNotifyObservers()) {
-    return;
-  }
-
-  nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
-  if (!os) {
-    return;
-  }
-
   nsTArray<nsCString> filtersArray;
   for (size_t i = 0; i < aFilterCount; ++i) {
     filtersArray.AppendElement(aFilters[i]);
   }
 
   nsCOMPtr<nsIProfilerStartParams> params =
     new nsProfilerStartParams(aEntries, aInterval, aFeatures, filtersArray);
 
-  os->NotifyObservers(params, "profiler-started", nullptr);
-}
-
-static void
-NotifyObservers(const char* aTopic)
-{
-  if (!CanNotifyObservers()) {
-    return;
-  }
-
-  nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
-  if (!os) {
-    return;
-  }
-
-  os->NotifyObservers(nullptr, aTopic, nullptr);
+  NotifyObservers("profiler-started", params);
 }
 
 static void
 locked_profiler_start(PSLockRef aLock, const int aEntries, double aInterval,
                       uint32_t aFeatures,
                       const char** aFilters, uint32_t aFilterCount);
 
 void