Bug 696399 - close connections in dom. r=honzab.moz.
authorRafael Ávila de Espíndola <respindola@mozilla.com>
Thu, 01 Dec 2011 08:30:23 -0500
changeset 81879 b6811f220aba188ace0bdb8ccf9992531a1d26a5
parent 81878 e07c407ae1b1c5a5f24309881d4808330d09a655
child 81880 4835dc9b8fc7a38fabd726dbceae68cf1a5478ed
push idunknown
push userunknown
push dateunknown
reviewershonzab.moz
bugs696399
milestone11.0a1
Bug 696399 - close connections in dom. r=honzab.moz.
dom/src/storage/nsDOMStorage.cpp
dom/src/storage/nsDOMStorage.h
dom/src/storage/nsDOMStorageDBWrapper.cpp
dom/src/storage/nsDOMStorageDBWrapper.h
dom/src/storage/nsDOMStoragePersistentDB.cpp
dom/src/storage/nsDOMStoragePersistentDB.h
--- a/dom/src/storage/nsDOMStorage.cpp
+++ b/dom/src/storage/nsDOMStorage.cpp
@@ -299,18 +299,16 @@ nsDOMStorageManager::Initialize()
   NS_ENSURE_SUCCESS(rv, rv);
   rv = os->AddObserver(gStorageManager, "perm-changed", true);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = os->AddObserver(gStorageManager, "browser:purge-domain-data", true);
   NS_ENSURE_SUCCESS(rv, rv);
   // Used for temporary table flushing
   rv = os->AddObserver(gStorageManager, "profile-before-change", true);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = os->AddObserver(gStorageManager, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
-  NS_ENSURE_SUCCESS(rv, rv);
   rv = os->AddObserver(gStorageManager, NS_DOMSTORAGE_FLUSH_TIMER_TOPIC, true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 //static
 nsDOMStorageManager*
@@ -324,16 +322,23 @@ nsDOMStorageManager::GetInstance()
 
 //static
 void
 nsDOMStorageManager::Shutdown()
 {
   NS_IF_RELEASE(gStorageManager);
   gStorageManager = nsnull;
 
+  ShutdownDB();
+}
+
+//static
+void
+nsDOMStorageManager::ShutdownDB()
+{
   delete DOMStorageImpl::gStorageDB;
   DOMStorageImpl::gStorageDB = nsnull;
 }
 
 static PLDHashOperator
 ClearStorage(nsDOMStorageEntry* aEntry, void* userArg)
 {
   aEntry->mStorage->ClearAll();
@@ -479,23 +484,24 @@ nsDOMStorageManager::Observe(nsISupports
 
     // Clear the storage entries for matching domains
     mStorages.EnumerateEntries(ClearStorageIfDomainMatches, &key);
 
     rv = DOMStorageImpl::InitDB();
     NS_ENSURE_SUCCESS(rv, rv);
 
     DOMStorageImpl::gStorageDB->RemoveOwner(aceDomain, true);
-  } else if (!strcmp(aTopic, "profile-before-change") || 
-             !strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
+  } else if (!strcmp(aTopic, "profile-before-change")) {
     if (DOMStorageImpl::gStorageDB) {
       DebugOnly<nsresult> rv =
         DOMStorageImpl::gStorageDB->FlushAndDeleteTemporaryTables(true);
       NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
                        "DOMStorage: temporary table commit failed");
+      DOMStorageImpl::gStorageDB->Close();
+      nsDOMStorageManager::ShutdownDB();
     }
   } else if (!strcmp(aTopic, NS_DOMSTORAGE_FLUSH_TIMER_TOPIC)) {
     if (DOMStorageImpl::gStorageDB) {
       DebugOnly<nsresult> rv =
         DOMStorageImpl::gStorageDB->FlushAndDeleteTemporaryTables(false);
       NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
                        "DOMStorage: temporary table commit failed");
     }
--- a/dom/src/storage/nsDOMStorage.h
+++ b/dom/src/storage/nsDOMStorage.h
@@ -124,16 +124,17 @@ public:
 
   nsresult ClearAllStorages();
 
   bool InPrivateBrowsingMode() { return mInPrivateBrowsing; }
 
   static nsresult Initialize();
   static nsDOMStorageManager* GetInstance();
   static void Shutdown();
+  static void ShutdownDB();
 
   /**
    * Checks whether there is any data waiting to be flushed from a temp table.
    */
   bool UnflushedDataExists();
 
   static nsDOMStorageManager* gStorageManager;
 
--- a/dom/src/storage/nsDOMStorageDBWrapper.cpp
+++ b/dom/src/storage/nsDOMStorageDBWrapper.cpp
@@ -73,16 +73,23 @@ void ReverseString(const nsCSubstring& s
 nsDOMStorageDBWrapper::nsDOMStorageDBWrapper()
 {
 }
 
 nsDOMStorageDBWrapper::~nsDOMStorageDBWrapper()
 {
 }
 
+void
+nsDOMStorageDBWrapper::Close()
+{
+  mPersistentDB.Close();
+  mChromePersistentDB.Close();
+}
+
 nsresult
 nsDOMStorageDBWrapper::Init()
 {
   nsresult rv;
 
   rv = mPersistentDB.Init(NS_LITERAL_STRING("webappsstore.sqlite"));
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/src/storage/nsDOMStorageDBWrapper.h
+++ b/dom/src/storage/nsDOMStorageDBWrapper.h
@@ -84,16 +84,21 @@ class nsSessionStorageEntry;
  * quota key for localStorage at http://foo.bar.com is "moc.rab.". */
 
 class nsDOMStorageDBWrapper
 {
 public:
   nsDOMStorageDBWrapper();
   ~nsDOMStorageDBWrapper();
 
+  /**
+   * Close the connections, finalizing all the cached statements.
+   */
+  void Close();
+
   nsresult
   Init();
 
   /**
    * Retrieve a list of all the keys associated with a particular domain.
    */
   nsresult
   GetAllKeys(DOMStorageImpl* aStorage,
--- a/dom/src/storage/nsDOMStoragePersistentDB.cpp
+++ b/dom/src/storage/nsDOMStoragePersistentDB.cpp
@@ -49,16 +49,18 @@
 #include "mozStorageHelper.h"
 #include "mozIStorageService.h"
 #include "mozIStorageBindingParamsArray.h"
 #include "mozIStorageBindingParams.h"
 #include "mozIStorageValueArray.h"
 #include "mozIStorageFunction.h"
 #include "nsNetUtil.h"
 
+using namespace mozilla;
+
 // Temporary tables for a storage scope will be flushed if found older
 // then this time in seconds since the load
 #define TEMP_TABLE_MAX_AGE (10) // seconds
 
 class nsReverseStringSQLFunction : public mozIStorageFunction
 {
   NS_DECL_ISUPPORTS
   NS_DECL_MOZISTORAGEFUNCTION
@@ -442,16 +444,38 @@ nsDOMStoragePersistentDB::Init(const nsS
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = transaction.Commit();
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
+void
+nsDOMStoragePersistentDB::Close()
+{
+  // Null the statements, this will finalize them.
+  mCopyToTempTableStatement = nsnull;
+  mCopyBackToDiskStatement = nsnull;
+  mDeleteTemporaryTableStatement = nsnull;
+  mGetAllKeysStatement = nsnull;
+  mGetKeyValueStatement = nsnull;
+  mInsertKeyStatement = nsnull;
+  mSetSecureStatement = nsnull;
+  mRemoveKeyStatement = nsnull;
+  mRemoveOwnerStatement = nsnull;
+  mRemoveStorageStatement = nsnull;
+  mRemoveAllStatement = nsnull;
+  mGetOfflineExcludedUsageStatement = nsnull;
+  mGetFullUsageStatement = nsnull;
+
+  DebugOnly<nsresult> rv = mConnection->Close();
+  MOZ_ASSERT(NS_SUCCEEDED(rv));
+}
+
 nsresult
 nsDOMStoragePersistentDB::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage)
 {
   TimeStamp timeStamp;
 
   if (!mTempTableLoads.Get(aStorage->GetScopeDBKey(), &timeStamp)) {
     nsresult rv;
 
--- a/dom/src/storage/nsDOMStoragePersistentDB.h
+++ b/dom/src/storage/nsDOMStoragePersistentDB.h
@@ -58,16 +58,22 @@ class nsDOMStoragePersistentDB : public 
 public:
   nsDOMStoragePersistentDB();
   ~nsDOMStoragePersistentDB() {}
 
   nsresult
   Init(const nsString& aDatabaseName);
 
   /**
+   * Close the connection, finalizing all the cached statements.
+   */
+  void
+  Close();
+
+  /**
    * Retrieve a list of all the keys associated with a particular domain.
    */
   nsresult
   GetAllKeys(DOMStorageImpl* aStorage,
              nsTHashtable<nsSessionStorageEntry>* aKeys);
 
   /**
    * Retrieve a value and secure flag for a key from storage.
@@ -194,16 +200,17 @@ protected:
   nsCOMPtr<mozIStorageStatement> mInsertKeyStatement;
   nsCOMPtr<mozIStorageStatement> mSetSecureStatement;
   nsCOMPtr<mozIStorageStatement> mRemoveKeyStatement;
   nsCOMPtr<mozIStorageStatement> mRemoveOwnerStatement;
   nsCOMPtr<mozIStorageStatement> mRemoveStorageStatement;
   nsCOMPtr<mozIStorageStatement> mRemoveAllStatement;
   nsCOMPtr<mozIStorageStatement> mGetOfflineExcludedUsageStatement;
   nsCOMPtr<mozIStorageStatement> mGetFullUsageStatement;
+  // If you add an statement, remember to null in in Close.
 
   nsCString mCachedOwner;
   PRInt32 mCachedUsage;
 
   // Maps ScopeDBKey to time of the temporary table load for that scope.
   // If a record is present, the temp table has been loaded. If it is not
   // present, the table has not yet been loaded or has alrady been flushed.
   nsDataHashtable<nsCStringHashKey, TimeStamp> mTempTableLoads;