diff --git a/toolkit/components/aboutmemory/tests/test_aboutcompartments.xul b/toolkit/components/aboutmemory/tests/test_aboutcompartments.xul index 15b0d73754ba..011196f571d9 100644 --- a/toolkit/components/aboutmemory/tests/test_aboutcompartments.xul +++ b/toolkit/components/aboutmemory/tests/test_aboutcompartments.xul @@ -26,6 +26,7 @@ // Remove all the real reporters and multi-reporters; save them to // restore at the end. + mgr.blockRegistration(); var e = mgr.enumerateReporters(); var realReporters = []; while (e.hasMoreElements()) { @@ -131,10 +132,10 @@ ]; for (var i = 0; i < fakeReporters.length; i++) { - mgr.registerReporter(fakeReporters[i]); + mgr.registerReporterEvenIfBlocked(fakeReporters[i]); } for (var i = 0; i < fakeMultiReporters.length; i++) { - mgr.registerMultiReporter(fakeMultiReporters[i]); + mgr.registerMultiReporterEvenIfBlocked(fakeMultiReporters[i]); } ]]> @@ -193,11 +194,13 @@ Ghost Windows\n\ mgr.unregisterMultiReporter(fakeMultiReporters[i]); } for (var i = 0; i < realReporters.length; i++) { - mgr.registerReporter(realReporters[i]); + mgr.registerReporterEvenIfBlocked(realReporters[i]); } for (var i = 0; i < realMultiReporters.length; i++) { - mgr.registerMultiReporter(realMultiReporters[i]); + mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]); } + mgr.unblockRegistration(); + SimpleTest.finish(); } diff --git a/toolkit/components/aboutmemory/tests/test_aboutmemory.xul b/toolkit/components/aboutmemory/tests/test_aboutmemory.xul index a5657049c182..d677553fc4bd 100644 --- a/toolkit/components/aboutmemory/tests/test_aboutmemory.xul +++ b/toolkit/components/aboutmemory/tests/test_aboutmemory.xul @@ -29,6 +29,7 @@ // Remove all the real reporters and multi-reporters; save them to // restore at the end. + mgr.blockRegistration(); let e = mgr.enumerateReporters(); let realReporters = []; while (e.hasMoreElements()) { @@ -162,10 +163,10 @@ } ]; for (let i = 0; i < fakeReporters.length; i++) { - mgr.registerReporter(fakeReporters[i]); + mgr.registerReporterEvenIfBlocked(fakeReporters[i]); } for (let i = 0; i < fakeMultiReporters.length; i++) { - mgr.registerMultiReporter(fakeMultiReporters[i]); + mgr.registerMultiReporterEvenIfBlocked(fakeMultiReporters[i]); } // mgr.explicit sums "heap-allocated" and all the appropriate NONHEAP ones: @@ -243,7 +244,7 @@ f("5th", "explicit/b/c/i/j", NONHEAP, 5 * KB) ]; for (let i = 0; i < fakeReporters2.length; i++) { - mgr.registerReporter(fakeReporters2[i]); + mgr.registerReporterEvenIfBlocked(fakeReporters2[i]); } fakeReporters = fakeReporters.concat(fakeReporters2); ]]> @@ -595,11 +596,13 @@ Other Measurements\n\ mgr.unregisterMultiReporter(fakeMultiReporters[i]); } for (let i = 0; i < realReporters.length; i++) { - mgr.registerReporter(realReporters[i]); + mgr.registerReporterEvenIfBlocked(realReporters[i]); } for (let i = 0; i < realMultiReporters.length; i++) { - mgr.registerMultiReporter(realMultiReporters[i]); + mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]); } + mgr.unblockRegistration(); + SimpleTest.finish(); } diff --git a/toolkit/components/aboutmemory/tests/test_aboutmemory2.xul b/toolkit/components/aboutmemory/tests/test_aboutmemory2.xul index 2fdb4a80da0b..7e7570068942 100644 --- a/toolkit/components/aboutmemory/tests/test_aboutmemory2.xul +++ b/toolkit/components/aboutmemory/tests/test_aboutmemory2.xul @@ -24,6 +24,7 @@ // Remove all the real reporters and multi-reporters; save them to // restore at the end. + mgr.blockRegistration(); let e = mgr.enumerateReporters(); let realReporters = []; while (e.hasMoreElements()) { @@ -78,7 +79,7 @@ ]; for (let i = 0; i < fakeReporters.length; i++) { - mgr.registerReporter(fakeReporters[i]); + mgr.registerReporterEvenIfBlocked(fakeReporters[i]); } ]]> @@ -97,11 +98,13 @@ mgr.unregisterReporter(fakeReporters[i]); } for (let i = 0; i < realReporters.length; i++) { - mgr.registerReporter(realReporters[i]); + mgr.registerReporterEvenIfBlocked(realReporters[i]); } for (let i = 0; i < realMultiReporters.length; i++) { - mgr.registerMultiReporter(realMultiReporters[i]); + mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]); } + mgr.unblockRegistration(); + SimpleTest.finish(); } diff --git a/toolkit/components/aboutmemory/tests/test_aboutmemory3.xul b/toolkit/components/aboutmemory/tests/test_aboutmemory3.xul index 1cdbc8f0de73..5dcdf1094c8d 100644 --- a/toolkit/components/aboutmemory/tests/test_aboutmemory3.xul +++ b/toolkit/components/aboutmemory/tests/test_aboutmemory3.xul @@ -24,6 +24,7 @@ // Remove all the real reporters and multi-reporters; save them to // restore at the end. + mgr.blockRegistration(); let e = mgr.enumerateReporters(); let realReporters = []; while (e.hasMoreElements()) { @@ -64,7 +65,7 @@ ]; for (let i = 0; i < fakeReporters.length; i++) { - mgr.registerReporter(fakeReporters[i]); + mgr.registerReporterEvenIfBlocked(fakeReporters[i]); } ]]> @@ -84,11 +85,13 @@ mgr.unregisterReporter(fakeReporters[i]); } for (let i = 0; i < realReporters.length; i++) { - mgr.registerReporter(realReporters[i]); + mgr.registerReporterEvenIfBlocked(realReporters[i]); } for (let i = 0; i < realMultiReporters.length; i++) { - mgr.registerMultiReporter(realMultiReporters[i]); + mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]); } + mgr.unblockRegistration(); + SimpleTest.finish(); } diff --git a/xpcom/base/nsIMemoryReporter.idl b/xpcom/base/nsIMemoryReporter.idl index 1e5444b024ed..c248a4fa043c 100644 --- a/xpcom/base/nsIMemoryReporter.idl +++ b/xpcom/base/nsIMemoryReporter.idl @@ -228,7 +228,7 @@ interface nsIMemoryMultiReporter : nsISupports readonly attribute int64_t explicitNonHeap; }; -[scriptable, builtinclass, uuid(0baaa958-3112-4952-b557-2a0c57eabb8f)] +[scriptable, builtinclass, uuid(70b0e608-8dbf-4dc7-b88f-f1c745c1b48c)] interface nsIMemoryReporterManager : nsISupports { /* @@ -267,6 +267,14 @@ interface nsIMemoryReporterManager : nsISupports */ void unregisterMultiReporter (in nsIMemoryMultiReporter reporter); + /** + * These functions should only be used for testing purposes. + */ + void blockRegistration(); + void unblockRegistration(); + void registerReporterEvenIfBlocked(in nsIMemoryReporter aReporter); + void registerMultiReporterEvenIfBlocked(in nsIMemoryMultiReporter aReporter); + /* * Initialize. */ diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 5dc2dd6e584f..4bf20c351b45 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -822,7 +822,8 @@ HashtableEnumerator::GetNext(nsISupports** aNext) } // anonymous namespace nsMemoryReporterManager::nsMemoryReporterManager() - : mMutex("nsMemoryReporterManager::mMutex") + : mMutex("nsMemoryReporterManager::mMutex"), + mIsRegistrationBlocked(false) { mReporters.Init(); mMultiReporters.Init(); @@ -877,13 +878,14 @@ DebugAssertRefcountIsNonZero(nsISupports* aObj) #endif } -NS_IMETHODIMP -nsMemoryReporterManager::RegisterReporter(nsIMemoryReporter *reporter) +nsresult +nsMemoryReporterManager::RegisterReporterHelper( + nsIMemoryReporter *reporter, bool aForce) { // This method is thread-safe. mozilla::MutexAutoLock autoLock(mMutex); - if (mReporters.Contains(reporter)) { + if ((mIsRegistrationBlocked && !aForce) || mReporters.Contains(reporter)) { return NS_ERROR_FAILURE; } @@ -908,12 +910,27 @@ nsMemoryReporterManager::RegisterReporter(nsIMemoryReporter *reporter) } NS_IMETHODIMP -nsMemoryReporterManager::RegisterMultiReporter(nsIMemoryMultiReporter *reporter) +nsMemoryReporterManager::RegisterReporter(nsIMemoryReporter *reporter) +{ + return RegisterReporterHelper(reporter, /* force = */ false); +} + +NS_IMETHODIMP +nsMemoryReporterManager::RegisterReporterEvenIfBlocked( + nsIMemoryReporter *reporter) +{ + return RegisterReporterHelper(reporter, /* force = */ true); +} + +nsresult +nsMemoryReporterManager::RegisterMultiReporterHelper( + nsIMemoryMultiReporter *reporter, bool aForce) { // This method is thread-safe. mozilla::MutexAutoLock autoLock(mMutex); - if (mMultiReporters.Contains(reporter)) { + if ((mIsRegistrationBlocked && !aForce) || + mMultiReporters.Contains(reporter)) { return NS_ERROR_FAILURE; } @@ -927,6 +944,19 @@ nsMemoryReporterManager::RegisterMultiReporter(nsIMemoryMultiReporter *reporter) return NS_OK; } +NS_IMETHODIMP +nsMemoryReporterManager::RegisterMultiReporter(nsIMemoryMultiReporter *reporter) +{ + return RegisterMultiReporterHelper(reporter, /* force = */ false); +} + +NS_IMETHODIMP +nsMemoryReporterManager::RegisterMultiReporterEvenIfBlocked( + nsIMemoryMultiReporter *reporter) +{ + return RegisterMultiReporterHelper(reporter, /* force = */ true); +} + NS_IMETHODIMP nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter *reporter) { @@ -955,6 +985,30 @@ nsMemoryReporterManager::UnregisterMultiReporter(nsIMemoryMultiReporter *reporte return NS_OK; } +NS_IMETHODIMP +nsMemoryReporterManager::BlockRegistration() +{ + // This method is thread-safe. + mozilla::MutexAutoLock autoLock(mMutex); + if (mIsRegistrationBlocked) { + return NS_ERROR_FAILURE; + } + mIsRegistrationBlocked = true; + return NS_OK; +} + +NS_IMETHODIMP +nsMemoryReporterManager::UnblockRegistration() +{ + // This method is thread-safe. + mozilla::MutexAutoLock autoLock(mMutex); + if (!mIsRegistrationBlocked) { + return NS_ERROR_FAILURE; + } + mIsRegistrationBlocked = false; + return NS_OK; +} + NS_IMETHODIMP nsMemoryReporterManager::GetResident(int64_t *aResident) { diff --git a/xpcom/base/nsMemoryReporterManager.h b/xpcom/base/nsMemoryReporterManager.h index 95faae1d610f..a581b1ab8358 100644 --- a/xpcom/base/nsMemoryReporterManager.h +++ b/xpcom/base/nsMemoryReporterManager.h @@ -23,9 +23,14 @@ public: virtual ~nsMemoryReporterManager(); private: + nsresult RegisterReporterHelper(nsIMemoryReporter *reporter, bool aForce); + nsresult RegisterMultiReporterHelper(nsIMemoryMultiReporter *reporter, + bool aForce); + nsTHashtable mReporters; nsTHashtable mMultiReporters; Mutex mMutex; + bool mIsRegistrationBlocked; }; #define NS_MEMORY_REPORTER_MANAGER_CID \