зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1022376: Properly shut down LoadMonitor threads r=jib
This commit is contained in:
Родитель
0a2850740d
Коммит
2cb6f6a37c
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче