Bug 1330184 - Register/unregister the IOInterposeObserver on the main thread, regardless of what thread the profiler is started / stopped on. r=njn draft
authorMarkus Stange <mstange@themasta.com>
Tue, 16 May 2017 17:35:05 -0400
changeset 586675 64def3fc572c55e2865f5adc570eb841fc759352
parent 586674 8c5d2b4ccacbbec92711a9561d4166e1e7c376c7
child 586676 7d7b377c2f369a21994a50dee736d0cc521be7d3
child 586820 681c553af3bf8da81a331b2d61d214ea8e867f65
push id61485
push userbmo:mstange@themasta.com
push dateTue, 30 May 2017 22:11:39 +0000
reviewersnjn
bugs1330184
milestone55.0a1
Bug 1330184 - Register/unregister the IOInterposeObserver on the main thread, regardless of what thread the profiler is started / stopped on. r=njn MozReview-Commit-ID: 8Y0rspxBJw3
tools/profiler/core/platform.cpp
tools/profiler/gecko/ProfilerIOInterposeObserver.h
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -292,26 +292,42 @@ private:
   {
     // Deep copy aFilters.
     MOZ_ALWAYS_TRUE(mFilters.resize(aFilterCount));
     for (uint32_t i = 0; i < aFilterCount; ++i) {
       mFilters[i] = aFilters[i];
     }
 
     if (mInterposeObserver) {
-      mozilla::IOInterposer::Register(mozilla::IOInterposeObserver::OpAll,
-                                      mInterposeObserver.get());
+      // We need to register the observer on the main thread, because we want
+      // to observe IO that happens on the main thread.
+      if (NS_IsMainThread()) {
+        IOInterposer::Register(IOInterposeObserver::OpAll, mInterposeObserver);
+      } else {
+        RefPtr<ProfilerIOInterposeObserver> observer = mInterposeObserver;
+        NS_DispatchToMainThread(NS_NewRunnableFunction([=]() {
+          IOInterposer::Register(IOInterposeObserver::OpAll, observer);
+        }));
+      }
     }
   }
 
   ~ActivePS()
   {
     if (mInterposeObserver) {
-      mozilla::IOInterposer::Unregister(mozilla::IOInterposeObserver::OpAll,
-                                        mInterposeObserver.get());
+      // We need to unregister the observer on the main thread, because that's
+      // where we've registered it.
+      if (NS_IsMainThread()) {
+        IOInterposer::Unregister(IOInterposeObserver::OpAll, mInterposeObserver);
+      } else {
+        RefPtr<ProfilerIOInterposeObserver> observer = mInterposeObserver;
+        NS_DispatchToMainThread(NS_NewRunnableFunction([=]() {
+          IOInterposer::Unregister(IOInterposeObserver::OpAll, observer);
+        }));
+      }
     }
   }
 
   bool ThreadSelected(const char* aThreadName)
   {
     // This function runs both on and off the main thread.
 
     MOZ_RELEASE_ASSERT(sInstance);
@@ -444,17 +460,17 @@ private:
   const UniquePtr<ProfileBuffer> mBuffer;
 
   // The current sampler thread. This class is not responsible for destroying
   // the SamplerThread object; the Destroy() method returns it so the caller
   // can destroy it.
   SamplerThread* const mSamplerThread;
 
   // The interposer that records main thread I/O.
-  const UniquePtr<mozilla::ProfilerIOInterposeObserver> mInterposeObserver;
+  const RefPtr<mozilla::ProfilerIOInterposeObserver> mInterposeObserver;
 
   // Is the profiler paused?
   bool mIsPaused;
 
 #if defined(GP_OS_linux)
   // Used to record whether the profiler was paused just before forking. False
   // at all times except just before/after forking.
   bool mWasPaused;
--- a/tools/profiler/gecko/ProfilerIOInterposeObserver.h
+++ b/tools/profiler/gecko/ProfilerIOInterposeObserver.h
@@ -3,26 +3,32 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef PROFILERIOINTERPOSEOBSERVER_H
 #define PROFILERIOINTERPOSEOBSERVER_H
 
 #ifdef MOZ_GECKO_PROFILER
 
 #include "mozilla/IOInterposer.h"
+#include "nsISupportsImpl.h"
 
 namespace mozilla {
 
 /**
  * This class is the observer that calls into the profiler whenever
  * main thread I/O occurs.
  */
 class ProfilerIOInterposeObserver final : public IOInterposeObserver
 {
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProfilerIOInterposeObserver)
+
 public:
   virtual void Observe(Observation& aObservation);
+
+protected:
+  virtual ~ProfilerIOInterposeObserver() {}
 };
 
 } // namespace mozilla
 
 #endif // MOZ_GECKO_PROFILER
 
 #endif // PROFILERIOINTERPOSEOBSERVER_H