Bug 970303 - Don't call DatabaseInfo::Remove() when app is killed, in case another app is still using the database. r=bent, a=1.4+
authorTed Clancy (:tedders1) <tclancy@mozilla.com>
Thu, 03 Apr 2014 16:57:40 -0700
changeset 192745 fcb53386d49e9b65ec60469723b799f3812ac4ea
parent 192744 4518ab9c258767ca84b0cec9489eb8c2fd21a99f
child 192746 dd3d371d6f039d9c6d6dc8ba9b3fc2bb1f1da833
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent, 1
bugs970303
milestone30.0a2
Bug 970303 - Don't call DatabaseInfo::Remove() when app is killed, in case another app is still using the database. r=bent, a=1.4+
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBDatabase.h
dom/indexedDB/ipc/IndexedDBParent.cpp
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -269,16 +269,24 @@ IDBDatabase::LastRelease()
   }
 }
 
 NS_IMETHODIMP_(void)
 IDBDatabase::Invalidate()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
+  InvalidateInternal(/* aIsDead */ false);
+}
+
+void
+IDBDatabase::InvalidateInternal(bool aIsDead)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
   if (IsInvalidated()) {
     return;
   }
 
   mInvalidated = true;
 
   // Make sure we're closed too.
   Close();
@@ -286,17 +294,23 @@ IDBDatabase::Invalidate()
   // When the IndexedDatabaseManager needs to invalidate databases, all it has
   // is an origin, so we call into the quota manager here to cancel any prompts
   // for our owner.
   nsPIDOMWindow* owner = GetOwner();
   if (owner) {
     QuotaManager::CancelPromptsForWindow(owner);
   }
 
-  DatabaseInfo::Remove(mDatabaseId);
+  // We want to forcefully remove in the child when the parent has invalidated
+  // us in IPC mode because the database might no longer exist.
+  // We don't want to forcefully remove in the parent when a child dies since
+  // other child processes may be using the referenced DatabaseInfo.
+  if (!aIsDead) {
+    DatabaseInfo::Remove(mDatabaseId);
+  }
 
   // And let the child process know as well.
   if (mActorParent) {
     NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
     mActorParent->Invalidate();
   }
 }
 
@@ -325,19 +339,17 @@ IDBDatabase::CloseInternal(bool aIsDead)
     mClosed = true;
 
     // If we're getting called from Unlink, avoid cloning the DatabaseInfo.
     {
       nsRefPtr<DatabaseInfo> previousInfo;
       mDatabaseInfo.swap(previousInfo);
 
       if (!aIsDead) {
-        nsRefPtr<DatabaseInfo> clonedInfo = previousInfo->Clone();
-
-        clonedInfo.swap(mDatabaseInfo);
+        mDatabaseInfo = previousInfo->Clone();
       }
     }
 
     QuotaManager* quotaManager = QuotaManager::Get();
     if (quotaManager) {
       quotaManager->OnStorageClosed(this);
     }
 
--- a/dom/indexedDB/IDBDatabase.h
+++ b/dom/indexedDB/IDBDatabase.h
@@ -48,16 +48,17 @@ class IndexedDBDatabaseChild;
 class IndexedDBDatabaseParent;
 struct ObjectStoreInfoGuts;
 
 class IDBDatabase : public IDBWrapperCache,
                     public nsIOfflineStorage
 {
   friend class AsyncConnectionHelper;
   friend class IndexedDatabaseManager;
+  friend class IndexedDBDatabaseParent;
   friend class IndexedDBDatabaseChild;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIFILESTORAGE
   NS_DECL_NSIOFFLINESTORAGE
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, IDBWrapperCache)
@@ -229,16 +230,17 @@ public:
 
   virtual void LastRelease() MOZ_OVERRIDE;
 
 private:
   IDBDatabase(IDBWrapperCache* aOwnerCache);
   ~IDBDatabase();
 
   void OnUnlink();
+  void InvalidateInternal(bool aIsDead);
 
   // The factory must be kept alive when IndexedDB is used in multiple
   // processes. If it dies then the entire actor tree will be destroyed with it
   // and the world will explode.
   nsRefPtr<IDBFactory> mFactory;
 
   nsRefPtr<DatabaseInfo> mDatabaseInfo;
 
--- a/dom/indexedDB/ipc/IndexedDBParent.cpp
+++ b/dom/indexedDB/ipc/IndexedDBParent.cpp
@@ -562,17 +562,17 @@ IndexedDBDatabaseParent::HandleDatabaseE
   MOZ_CRASH("Unexpected message type!");
 }
 
 void
 IndexedDBDatabaseParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (mDatabase) {
     mDatabase->SetActor(static_cast<IndexedDBDatabaseParent*>(nullptr));
-    mDatabase->Invalidate();
+    mDatabase->InvalidateInternal(/* aIsDead */ true);
   }
 }
 
 bool
 IndexedDBDatabaseParent::RecvClose(const bool& aUnlinked)
 {
   MOZ_ASSERT(mDatabase);