Bug 1267820 - Fix HTTP cache2 leak after shutdown, don't setup purging timer after shutdown. r=michal a=ritu
authorHonza Bambas <honzab.moz@firemni.cz>
Tue, 20 Sep 2016 06:53:00 -0400
changeset 350409 a843ec6679418da24075e1e1f6352cc963022c52
parent 350408 a0907d658080db8c111fc78c5332b31f6c904f71
child 350410 a4b2d61482b8311f471a232463c02bb15fb8390f
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal, ritu
bugs1267820
milestone50.0
Bug 1267820 - Fix HTTP cache2 leak after shutdown, don't setup purging timer after shutdown. r=michal a=ritu
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);
   }