Bug 1330184 - Allow notifying observers for profiler state changes on background threads. r=njn
☠☠ backed out by df065d529e85 ☠ ☠
authorMarkus Stange <mstange@themasta.com>
Mon, 15 May 2017 19:43:08 -0400
changeset 360029 52489c7eadaf8cab111eef93187c7ecb1482fe58
parent 360028 ff997cf7f59424cc221a41f357fe811d23db239e
child 360030 e13b9e798e16185e54435a0b926970e8de134804
push id31867
push userryanvm@gmail.com
push dateTue, 23 May 2017 14:09:01 +0000
treeherdermozilla-central@4f874bc1e424 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1330184
milestone55.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 1330184 - 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. This can result in awkward orders of the notifications if the profiler functions are called in quick succession on both the main thread and another thread, but I'm not sure what to do about that. MozReview-Commit-ID: GlkVwGTa2b4
tools/profiler/core/platform.cpp
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -527,29 +527,16 @@ MOZ_THREAD_LOCAL(ThreadInfo*) TLSInfo::s
 // This second pointer isn't ideal, but does provide a way to satisfy those
 // constraints. TLSInfo manages it, except for the uses in
 // profiler_call_{enter,exit}.
 MOZ_THREAD_LOCAL(PseudoStack*) sPseudoStack;
 
 // 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:
@@ -1987,52 +1974,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