Bug 1022376: Properly shut down LoadMonitor threads r=jib

This commit is contained in:
Randell Jesup 2014-06-08 18:37:14 -04:00
Родитель 0a2850740d
Коммит 2cb6f6a37c
2 изменённых файлов: 31 добавлений и 6 удалений

Просмотреть файл

@ -58,6 +58,7 @@ LoadManager::LoadManager(int aLoadMeasurementInterval,
LoadManager::~LoadManager()
{
LOG(("LoadManager: shutting down LoadMonitor"));
mLoadMonitor->Shutdown();
}

Просмотреть файл

@ -149,11 +149,17 @@ private:
void LoadMonitor::Shutdown()
{
MutexAutoLock lock(mLock);
if (mLoadInfoThread) {
mShutdownPending = true;
mCondVar.Notify();
{
MutexAutoLock lock(mLock);
LOG(("LoadMonitor: shutting down"));
mShutdownPending = true;
mCondVar.Notify();
}
// Note: can't just call ->Shutdown() from here; that spins the event
// loop here, causing re-entrancy issues if we're invoked from cycle
// collection. Argh.
mLoadInfoThread = nullptr;
nsRefPtr<LoadMonitorRemoveObserver> remObsRunner = new LoadMonitorRemoveObserver(this);
@ -516,8 +522,10 @@ class LoadInfoCollectRunner : public nsRunnable
{
public:
LoadInfoCollectRunner(nsRefPtr<LoadMonitor> loadMonitor,
RefPtr<LoadInfo> loadInfo)
: mLoadUpdateInterval(loadMonitor->mLoadUpdateInterval),
RefPtr<LoadInfo> loadInfo,
nsIThread *loadInfoThread)
: mThread(loadInfoThread),
mLoadUpdateInterval(loadMonitor->mLoadUpdateInterval),
mLoadNoiseCounter(0)
{
mLoadMonitor = loadMonitor;
@ -526,6 +534,19 @@ public:
NS_IMETHOD Run()
{
if (NS_IsMainThread()) {
if (mThread) {
// Don't leak threads!
mThread->Shutdown(); // can't Shutdown from the thread itself, darn
// Don't null out mThread!
// See bug 999104. We must hold a ref to the thread across Dispatch()
// since the internal mThread ref could be released while processing
// the Dispatch(), and Dispatch/PutEvent itself doesn't hold a ref; it
// assumes the caller does.
}
return NS_OK;
}
MutexAutoLock lock(mLoadMonitor->mLock);
while (!mLoadMonitor->mShutdownPending) {
mLoadInfo->UpdateSystemLoad();
@ -543,10 +564,13 @@ public:
mLoadMonitor->mCondVar.Wait(PR_MillisecondsToInterval(mLoadUpdateInterval));
}
// ok, we need to exit safely and can't shut ourselves down (DARN)
NS_DispatchToMainThread(this);
return NS_OK;
}
private:
nsCOMPtr<nsIThread> mThread;
RefPtr<LoadInfo> mLoadInfo;
nsRefPtr<LoadMonitor> mLoadMonitor;
int mLoadUpdateInterval;
@ -605,7 +629,7 @@ LoadMonitor::Init(nsRefPtr<LoadMonitor> &self)
NS_NewNamedThread("Sys Load Info", getter_AddRefs(mLoadInfoThread));
nsRefPtr<LoadInfoCollectRunner> runner =
new LoadInfoCollectRunner(self, load_info);
new LoadInfoCollectRunner(self, load_info, mLoadInfoThread);
mLoadInfoThread->Dispatch(runner, NS_DISPATCH_NORMAL);
return NS_OK;