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 175738 a7735f4df76628b2a1c846fab9ea78df6af1a6ba
parent 175737 b70ae46026f388afa78544861467be74446f7994
child 175739 54b3b3fa8bbe27c31d9a453d57b572e5fc0e9f52
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey, bajaj
bugs924348
milestone28.0a2
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
@@ -1336,19 +1336,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;
     }
 
@@ -1359,26 +1357,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