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
--- 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