Bug 924348 - Intermittent PROCESS-CRASH | /tests/dom/indexedDB/test/test_add_put.html | application crashed [@ sqlite3LeaveMutexAndCloseZombie] or [@ hashDestroy]. r=khuey a=bajaj
authorJan Varga <jan.varga@gmail.com>
Mon, 13 Jan 2014 13:27:19 -0500
changeset 167915 c33c9dde355c2487f93190638489a67f3d557aa6
parent 167914 fb53f8276dff05d30f297cd1ee772d740cf1f3f3
child 167916 12e33df9b2061e335aeff968274bde61ae0a7dbe
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey, bajaj
bugs924348
milestone27.0
Bug 924348 - Intermittent PROCESS-CRASH | /tests/dom/indexedDB/test/test_add_put.html | application crashed [@ sqlite3LeaveMutexAndCloseZombie] or [@ hashDestroy]. r=khuey a=bajaj
dom/quota/QuotaManager.cpp
dom/quota/QuotaObject.h
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -1335,19 +1335,17 @@ QuotaManager::GetQuotaObject(Persistence
   if (exists) {
     rv = aFile->GetFileSize(&fileSize);
     NS_ENSURE_SUCCESS(rv, nullptr);
   }
   else {
     fileSize = 0;
   }
 
-  // We need this extra raw pointer because we can't assign to the smart
-  // pointer directly since QuotaObject::AddRef needs to acquire the same mutex.
-  QuotaObject* quotaObject;
+  nsRefPtr<QuotaObject> result;
   {
     MutexAutoLock lock(mQuotaMutex);
 
     GroupInfoPair* pair;
     if (!mGroupInfoPairs.Get(aGroup, &pair)) {
       return nullptr;
     }
 
@@ -1358,26 +1356,36 @@ QuotaManager::GetQuotaObject(Persistence
     }
 
     nsRefPtr<OriginInfo> originInfo = groupInfo->LockedGetOriginInfo(aOrigin);
 
     if (!originInfo) {
       return nullptr;
     }
 
+    // We need this extra raw pointer because we can't assign to the smart
+    // pointer directly since QuotaObject::AddRef would try to acquire the same
+    // mutex.
+    QuotaObject* quotaObject;
     if (!originInfo->mQuotaObjects.Get(path, &quotaObject)) {
+      // Create a new QuotaObject.
       quotaObject = new QuotaObject(originInfo, path, fileSize);
+
+      // Put it to the hashtable. The hashtable is not responsible to delete
+      // the QuotaObject.
       originInfo->mQuotaObjects.Put(path, quotaObject);
-      // The hashtable is not responsible to delete the QuotaObject.
     }
+
+    // Addref the QuotaObject and move the ownership to the result. This must
+    // happen before we unlock!
+    result = quotaObject->LockedAddRef();
   }
 
   // The caller becomes the owner of the QuotaObject, that is, the caller is
   // is responsible to delete it when the last reference is removed.
-  nsRefPtr<QuotaObject> result = quotaObject;
   return result.forget();
 }
 
 already_AddRefed<QuotaObject>
 QuotaManager::GetQuotaObject(PersistenceType aPersistenceType,
                              const nsACString& aGroup,
                              const nsACString& aOrigin,
                              const nsAString& aPath)
--- a/dom/quota/QuotaObject.h
+++ b/dom/quota/QuotaObject.h
@@ -45,16 +45,27 @@ private:
     MOZ_COUNT_CTOR(QuotaObject);
   }
 
   ~QuotaObject()
   {
     MOZ_COUNT_DTOR(QuotaObject);
   }
 
+  already_AddRefed<QuotaObject>
+  LockedAddRef()
+  {
+    AssertCurrentThreadOwnsQuotaMutex();
+
+    ++mRefCnt;
+
+    nsRefPtr<QuotaObject> result = dont_AddRef(this);
+    return result.forget();
+  }
+
   mozilla::ThreadSafeAutoRefCnt mRefCnt;
 
   OriginInfo* mOriginInfo;
   nsString mPath;
   int64_t mSize;
 };
 
 class OriginInfo