Bug 999888: Make IOInterposer leakcheck-friendly; f=ehsan, r=froydnj

--HG--
extra : rebase_source : ff65dd0f8ab4f28bf53b52f71cda1793df9a108a
This commit is contained in:
Aaron Klotz 2014-04-29 11:29:43 -06:00
parent df4b523fb5
commit 6e588eb232
3 changed files with 39 additions and 18 deletions

View File

@ -4036,8 +4036,6 @@ XREMain::XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
GeckoProfilerInitRAII profilerGuard(&aLocal);
PROFILER_LABEL("Startup", "XRE_Main");
mozilla::IOInterposerInit ioInterposerGuard;
nsresult rv = NS_OK;
gArgc = argc;
@ -4053,6 +4051,8 @@ XREMain::XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
ScopedLogging log;
mozilla::IOInterposerInit ioInterposerGuard;
#if defined(MOZ_WIDGET_GTK)
#if defined(MOZ_MEMORY) || defined(__FreeBSD__) || defined(__NetBSD__)
// Disable the slice allocator, since jemalloc already uses similar layout

View File

@ -11,15 +11,7 @@
#include "MainThreadIOLogger.h"
#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"
#if defined(MOZILLA_INTERNAL_API)
// We need to undefine MOZILLA_INTERNAL_API for RefPtr.h because IOInterposer
// does not clean up its data before shutdown.
#undef MOZILLA_INTERNAL_API
#include "mozilla/RefPtr.h"
#define MOZILLA_INTERNAL_API
#else
#include "mozilla/RefPtr.h"
#endif // defined(MOZILLA_INTERNAL_API)
#include "mozilla/StaticPtr.h"
#include "mozilla/ThreadLocal.h"
#if !defined(XP_WIN)
@ -86,6 +78,12 @@ public:
, mIsHandlingObservation(false)
, mCurrentGeneration(0)
{
MOZ_COUNT_CTOR(PerThreadData);
}
~PerThreadData()
{
MOZ_COUNT_DTOR(PerThreadData);
}
void
@ -174,6 +172,15 @@ public:
mObserverLists = aNewLists;
}
inline void
ClearObserverLists()
{
if (mObserverLists) {
mCurrentGeneration = 0;
mObserverLists = nullptr;
}
}
private:
bool mIsMainThread;
bool mIsHandlingObservation;
@ -188,10 +195,12 @@ public:
: mObservedOperations(IOInterposeObserver::OpNone)
, mIsEnabled(true)
{
MOZ_COUNT_CTOR(MasterList);
}
~MasterList()
{
MOZ_COUNT_DTOR(MasterList);
}
inline void
@ -313,7 +322,7 @@ public:
mObserverLists = newLists;
mCurrentGeneration++;
}
void
Update(PerThreadData &aPtd)
{
@ -474,7 +483,13 @@ IOInterposeObserver::IsMainThread()
void
IOInterposer::Clear()
{
/* Clear() is a no-op on opt builds so that we may continue to trap I/O until
process termination. In debug builds we need to shut down IOInterposer so
that all references are properly released and refcnt log remains clean. */
#if defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)
UnregisterCurrentThread();
sMasterList = nullptr;
#endif
}
void
@ -489,11 +504,6 @@ IOInterposer::Disable()
void
IOInterposer::Report(IOInterposeObserver::Observation& aObservation)
{
MOZ_ASSERT(sMasterList);
if (!sMasterList) {
return;
}
PerThreadData* ptd = sThreadLocalData.get();
if (!ptd) {
// In this case the current thread is not registered with IOInterposer.
@ -501,6 +511,13 @@ IOInterposer::Report(IOInterposeObserver::Observation& aObservation)
// we're not registered. That could potentially perform poorly, though.
return;
}
if (!sMasterList) {
// If there is no longer a master list then we should clear the local one.
ptd->ClearObserverLists();
return;
}
sMasterList->Update(*ptd);
// Don't try to report if there's nobody listening.

View File

@ -281,8 +281,12 @@ public:
#endif
}
// No destructor needed at the moment -- this stuff stays active for the
// life of the process. This may change in the future.
~IOInterposerInit()
{
#if defined(MOZ_ENABLE_PROFILER_SPS)
IOInterposer::Clear();
#endif
}
};
} // namespace mozilla