Bug 1267820 - Fix HTTP cache2 leak after shutdown, don't setup purging timer after shutdown. r=michal
authorHonza Bambas <honzab.moz@firemni.cz>
Tue, 20 Sep 2016 06:53:00 -0400
changeset 314664 9a370db31b854832c7a67393be49d4c6c3fde3c6
parent 314663 073e1d56b6cd3019082a3aef7ca4f399d2fc108b
child 314665 5f261677780f86df3e090e099676069023133c38
push id30732
push usercbook@mozilla.com
push dateWed, 21 Sep 2016 10:04:03 +0000
treeherdermozilla-central@560b2c805bf7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1267820
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1267820 - Fix HTTP cache2 leak after shutdown, don't setup purging timer after shutdown. r=michal
netwerk/cache2/CacheStorageService.cpp
--- a/netwerk/cache2/CacheStorageService.cpp
+++ b/netwerk/cache2/CacheStorageService.cpp
@@ -130,54 +130,62 @@ CacheStorageService::CacheStorageService
 CacheStorageService::~CacheStorageService()
 {
   LOG(("CacheStorageService::~CacheStorageService"));
   sSelf = nullptr;
 }
 
 void CacheStorageService::Shutdown()
 {
+  mozilla::MutexAutoLock lock(mLock);
+
   if (mShutdown)
     return;
 
   LOG(("CacheStorageService::Shutdown - start"));
 
   mShutdown = true;
 
   nsCOMPtr<nsIRunnable> event =
     NewRunnableMethod(this, &CacheStorageService::ShutdownBackground);
   Dispatch(event);
 
-  {
-    mozilla::MutexAutoLock lock(mLock);
 #ifdef NS_FREE_PERMANENT_DATA
-    sGlobalEntryTables->Clear();
-    delete sGlobalEntryTables;
+  sGlobalEntryTables->Clear();
+  delete sGlobalEntryTables;
 #endif
-    sGlobalEntryTables = nullptr;
-  }
+  sGlobalEntryTables = nullptr;
 
   LOG(("CacheStorageService::Shutdown - done"));
 }
 
 void CacheStorageService::ShutdownBackground()
 {
+  LOG(("CacheStorageService::ShutdownBackground - start"));
+
   MOZ_ASSERT(IsOnManagementThread());
 
-  // Cancel purge timer to avoid leaking.
-  if (mPurgeTimer) {
-    mPurgeTimer->Cancel();
+  {
+    mozilla::MutexAutoLock lock(mLock);
+
+    // Cancel purge timer to avoid leaking.
+    if (mPurgeTimer) {
+      LOG(("  freeing the timer"));
+      mPurgeTimer->Cancel();
+    }
   }
 
 #ifdef NS_FREE_PERMANENT_DATA
   Pool(false).mFrecencyArray.Clear();
   Pool(false).mExpirationArray.Clear();
   Pool(true).mFrecencyArray.Clear();
   Pool(true).mExpirationArray.Clear();
 #endif
+
+  LOG(("CacheStorageService::ShutdownBackground - done"));
 }
 
 // Internal management methods
 
 namespace {
 
 // WalkCacheRunnable
 // Base class for particular storage entries visiting
@@ -1253,29 +1261,45 @@ CacheStorageService::MemoryPool::OnMemor
     return false;
 
   return mMemorySize > Limit();
 }
 
 void
 CacheStorageService::SchedulePurgeOverMemoryLimit()
 {
+  LOG(("CacheStorageService::SchedulePurgeOverMemoryLimit"));
+
   mozilla::MutexAutoLock lock(mLock);
 
-  if (mPurgeTimer)
+  if (mShutdown) {
+    LOG(("  past shutdown"));
     return;
+  }
+
+  if (mPurgeTimer) {
+    LOG(("  timer already up"));
+    return;
+  }
 
   mPurgeTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
-  if (mPurgeTimer)
-    mPurgeTimer->InitWithCallback(this, 1000, nsITimer::TYPE_ONE_SHOT);
+  if (mPurgeTimer) {
+    nsresult rv;
+    rv = mPurgeTimer->InitWithCallback(this, 1000, nsITimer::TYPE_ONE_SHOT);
+    LOG(("  timer init rv=0x%08x", rv));
+  }
 }
 
 NS_IMETHODIMP
 CacheStorageService::Notify(nsITimer* aTimer)
 {
+  LOG(("CacheStorageService::Notify"));
+
+  mozilla::MutexAutoLock lock(mLock);
+
   if (aTimer == mPurgeTimer) {
     mPurgeTimer = nullptr;
 
     nsCOMPtr<nsIRunnable> event =
       NewRunnableMethod(this, &CacheStorageService::PurgeOverMemoryLimit);
     Dispatch(event);
   }