Bug 970303 - Don't call DatabaseInfo::Remove() when app is killed, in case another app is still using the database. r=bent
authorTed Clancy (:tedders1) <tclancy@mozilla.com>
Thu, 03 Apr 2014 16:57:40 -0700
changeset 177760 c8388e3bac74adf61343c92794c51e885c6c3b67
parent 177759 6892cdd30dd729f6bf8a0b28beb53af2cf428981
child 177761 2d6b24e35aefec005c061ece80ca5511dcfc7283
push id6122
push usercbook@mozilla.com
push dateThu, 10 Apr 2014 10:01:30 +0000
treeherderb2g-inbound@2d6b24e35aef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs970303
milestone31.0a1
Bug 970303 - Don't call DatabaseInfo::Remove() when app is killed, in case another app is still using the database. r=bent
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBDatabase.h
dom/indexedDB/ipc/IndexedDBParent.cpp
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -271,16 +271,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();
@@ -288,17 +296,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();
   }
 }
 
@@ -327,19 +341,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
@@ -49,16 +49,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)
@@ -231,16 +232,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);