Backing out bug 536978, due to a Storage assertion causing orange. CLOSED TREE
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 12 Mar 2010 17:41:28 +0100
changeset 39359 c465e05b4e881357b43cc7938d136a97a302931d
parent 39358 2d1342ee572b73eb1a699283f30dd608961f07f9
child 39360 48ef8a7c1079824e113ee297bc691fbb38debcb6
push idunknown
push userunknown
push dateunknown
bugs536978
milestone1.9.3a3pre
Backing out bug 536978, due to a Storage assertion causing orange. CLOSED TREE
netwerk/cookie/src/nsCookieService.cpp
netwerk/cookie/src/nsCookieService.h
storage/public/storage.h
--- a/netwerk/cookie/src/nsCookieService.cpp
+++ b/netwerk/cookie/src/nsCookieService.cpp
@@ -64,19 +64,20 @@
 #include "nsAutoPtr.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 #include "prtime.h"
 #include "prprf.h"
 #include "nsNetUtil.h"
 #include "nsNetCID.h"
 #include "nsAppDirectoryServiceDefs.h"
+#include "mozIStorageService.h"
+#include "mozStorageHelper.h"
 #include "nsIPrivateBrowsingService.h"
 #include "nsNetCID.h"
-#include "mozilla/storage.h"
 
 /******************************************************************************
  * nsCookieService impl:
  * useful types & constants
  ******************************************************************************/
 
 // XXX_hack. See bug 178993.
 // This is a hack to hide HttpOnly cookies from older browsers
@@ -336,137 +337,16 @@ LogSuccess(PRBool aSetCookie, nsIURI *aH
 
 #else
 #define COOKIE_LOGFAILURE(a, b, c, d)    PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
 #define COOKIE_LOGSUCCESS(a, b, c, d, e) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
 #define COOKIE_LOGEVICTED(a)             PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
 #define COOKIE_LOGSTRING(a, b)           PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
 #endif
 
-#ifdef DEBUG
-#define NS_ASSERT_SUCCESS(res)                                               \
-  PR_BEGIN_MACRO                                                             \
-  nsresult __rv = res; /* Do not evaluate |res| more than once! */           \
-  if (NS_FAILED(__rv)) {                                                     \
-    char *msg = PR_smprintf("NS_ASSERT_SUCCESS(%s) failed with result 0x%X", \
-                            #res, __rv);                                     \
-    NS_ASSERTION(NS_SUCCEEDED(__rv), msg);                                   \
-    PR_smprintf_free(msg);                                                   \
-  }                                                                          \
-  PR_END_MACRO
-#else
-#define NS_ASSERT_SUCCESS(res) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
-#endif
-
-namespace {
-/******************************************************************************
- * DBListenerErrorHandler imp:
- * Parent class for our async storage listeners that handles the logging of
- * errors.
- ******************************************************************************/
-class DBListenerErrorHandler : public mozIStorageStatementCallback
-{
-protected:
-  virtual const char *GetOpType() = 0;
-
-public:
-  NS_DECL_ISUPPORTS
-
-  NS_IMETHOD HandleError(mozIStorageError* aError)
-  {
-#ifdef PR_LOGGING
-    PRInt32 result = -1;
-    aError->GetResult(&result);
-    nsCAutoString message;
-    aError->GetMessage(message);
-    COOKIE_LOGSTRING(PR_LOG_WARNING,
-                     ("Error %d occurred while performing a %s operation.  Message: `%s`\n",
-                      result, GetOpType(), message.get()));
-#endif
-    return NS_OK;
-  }
-};
-NS_IMETHODIMP_(nsrefcnt) DBListenerErrorHandler::AddRef() { return 2; }
-NS_IMETHODIMP_(nsrefcnt) DBListenerErrorHandler::Release() { return 1; }
-NS_IMPL_QUERY_INTERFACE1(DBListenerErrorHandler, mozIStorageStatementCallback)
-
-/******************************************************************************
- * InsertCookieDBListener imp:
- * Static mozIStorageStatementCallback used to track asynchronous insertion
- * operations.
- ******************************************************************************/
-class InsertCookieDBListener : public DBListenerErrorHandler
-{
-protected:
-  virtual const char *GetOpType() { return "INSERT"; }
-
-public:
-  NS_IMETHOD HandleResult(mozIStorageResultSet*)
-  {
-    NS_NOTREACHED("Unexpected call to InsertCookieDBListener::HandleResult");
-    return NS_OK;
-  }
-  NS_IMETHOD HandleCompletion(PRUint16 aReason)
-  {
-    return NS_OK;
-  }
-};
-
-static InsertCookieDBListener sInsertCookieDBListener;
-
-/******************************************************************************
- * UpdateCookieDBListener imp:
- * Static mozIStorageStatementCallback used to track asynchronous update
- * operations.
- ******************************************************************************/
-class UpdateCookieDBListener : public DBListenerErrorHandler
-{
-protected:
-  virtual const char *GetOpType() { return "UPDATE"; }
-
-public:
-  NS_IMETHOD HandleResult(mozIStorageResultSet*)
-  {
-    NS_NOTREACHED("Unexpected call to UpdateCookieDBListener::HandleResult");
-    return NS_OK;
-  }
-  NS_IMETHOD HandleCompletion(PRUint16 aReason)
-  {
-    return NS_OK;
-  }
-};
-
-static UpdateCookieDBListener sUpdateCookieDBListener;
-
-/******************************************************************************
- * RemoveCookieDBListener imp:
- * Static mozIStorageStatementCallback used to track asynchronous removal
- * operations.
- ******************************************************************************/
-class RemoveCookieDBListener :  public DBListenerErrorHandler
-{
-protected:
-  virtual const char *GetOpType() { return "REMOVE"; }
-
-public:
-  NS_IMETHOD HandleResult(mozIStorageResultSet*)
-  {
-    NS_NOTREACHED("Unexpected call to RemoveCookieDBListener::HandleResult");
-    return NS_OK;
-  }
-  NS_IMETHOD HandleCompletion(PRUint16 aReason)
-  {
-    return NS_OK;
-  }
-};
-
-static RemoveCookieDBListener sRemoveCookieDBListener;
-
-} // anonymous namespace
-
 /******************************************************************************
  * nsCookieService impl:
  * singleton instance ctor/dtor methods
  ******************************************************************************/
 
 nsCookieService *nsCookieService::gCookieService = nsnull;
 
 nsCookieService*
@@ -788,20 +668,17 @@ nsCookieService::CloseDB()
 {
   NS_ASSERTION(!mPrivateDBState.dbConn, "private DB connection should always be null");
 
   // finalize our statements and close the db connection for the default state.
   // since we own these objects, nulling the pointers is sufficient here.
   mDefaultDBState.stmtInsert = nsnull;
   mDefaultDBState.stmtDelete = nsnull;
   mDefaultDBState.stmtUpdate = nsnull;
-  if (mDefaultDBState.dbConn) {
-    mDefaultDBState.dbConn->AsyncClose(NULL);
-    mDefaultDBState.dbConn = nsnull;
-  }
+  mDefaultDBState.dbConn = nsnull;
 }
 
 nsCookieService::~nsCookieService()
 {
   CloseDB();
 
   gCookieService = nsnull;
 }
@@ -969,37 +846,24 @@ nsCookieService::SetCookieStringInternal
   PRInt64 serverTime;
   if (aServerTime &&
       PR_ParseTimeString(aServerTime, PR_TRUE, &tempServerTime) == PR_SUCCESS) {
     serverTime = tempServerTime / PR_USEC_PER_SEC;
   } else {
     serverTime = PR_Now() / PR_USEC_PER_SEC;
   }
 
-  // We may be adding a bunch of cookies to the DB, so we use async batching
-  // with storage to make this super fast.
-  nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
-  if (mDBState->dbConn) {
-    mDBState->stmtInsert->NewBindingParamsArray(getter_AddRefs(paramsArray));
-  }
-
+  // start a transaction on the storage db, to optimize insertions.
+  // transaction will automically commit on completion
+  mozStorageTransaction transaction(mDBState->dbConn, PR_TRUE);
+ 
   // switch to a nice string type now, and process each cookie in the header
   nsDependentCString cookieHeader(aCookieHeader);
   while (SetCookieInternal(aHostURI, aChannel, baseDomain, requireHostMatch,
-                           cookieHeader, serverTime, aFromHttp, paramsArray));
-
-  // If we had a params array, go ahead and write it out to disk now.
-  if (paramsArray) {
-    rv = mDBState->stmtInsert->BindParameters(paramsArray);
-    NS_ASSERT_SUCCESS(rv);
-    nsCOMPtr<mozIStoragePendingStatement> handle;
-    rv = mDBState->stmtInsert->ExecuteAsync(&sInsertCookieDBListener,
-                                            getter_AddRefs(handle));
-    NS_ASSERT_SUCCESS(rv);
-  }
+                           cookieHeader, serverTime, aFromHttp));
 
   return NS_OK;
 }
 
 // notify observers that a cookie was rejected due to the users' prefs.
 void
 nsCookieService::NotifyRejected(nsIURI *aHostURI)
 {
@@ -1268,17 +1132,17 @@ nsCookieService::Read()
                        lastAccessed,
                        creationID,
                        PR_FALSE,
                        isSecure,
                        isHttpOnly);
     if (!newCookie)
       return NS_ERROR_OUT_OF_MEMORY;
 
-    if (!AddCookieToList(baseDomain, newCookie, NULL, PR_FALSE))
+    if (!AddCookieToList(baseDomain, newCookie, PR_FALSE))
       // It is purpose that created us; purpose that connects us;
       // purpose that pulls us; that guides us; that drives us.
       // It is purpose that defines us; purpose that binds us.
       // When a cookie no longer has purpose, it has a choice:
       // it can return to the source to be deleted, or it can go
       // into exile, and stay hidden inside the Matrix.
       // Let's choose deletion.
       delete newCookie;
@@ -1295,16 +1159,20 @@ nsCookieService::ImportCookies(nsIFile *
   nsresult rv;
   nsCOMPtr<nsIInputStream> fileInputStream;
   rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), aCookieFile);
   if (NS_FAILED(rv)) return rv;
 
   nsCOMPtr<nsILineInputStream> lineInputStream = do_QueryInterface(fileInputStream, &rv);
   if (NS_FAILED(rv)) return rv;
 
+  // start a transaction on the storage db, to optimize insertions.
+  // transaction will automically commit on completion
+  mozStorageTransaction transaction(mDBState->dbConn, PR_TRUE);
+
   static const char kTrue[] = "TRUE";
 
   nsCAutoString buffer, baseDomain;
   PRBool isMore = PR_TRUE;
   PRInt32 hostIndex, isDomainIndex, pathIndex, secureIndex, expiresIndex, nameIndex, cookieIndex;
   nsASingleFragmentCString::char_iterator iter;
   PRInt32 numInts;
   PRInt64 expires;
@@ -1335,23 +1203,16 @@ nsCookieService::ImportCookies(nsIFile *
    * in a comment, so they don't expose HttpOnly cookies to JS.
    *
    * The format for HttpOnly cookies is
    *
    * #HttpOnly_host \t isDomain \t path \t secure \t expires \t name \t cookie
    *
    */
 
-  // We will likely be adding a bunch of cookies to the DB, so we use async
-  // batching with storage to make this super fast.
-  nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
-  if (mDBState->dbConn) {
-    mDBState->stmtInsert->NewBindingParamsArray(getter_AddRefs(paramsArray));
-  }
-
   while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore))) {
     if (StringBeginsWith(buffer, NS_LITERAL_CSTRING(kHttpOnlyPrefix))) {
       isHttpOnly = PR_TRUE;
       hostIndex = sizeof(kHttpOnlyPrefix) - 1;
     } else if (buffer.IsEmpty() || buffer.First() == '#') {
       continue;
     } else {
       isHttpOnly = PR_FALSE;
@@ -1412,36 +1273,22 @@ nsCookieService::ImportCookies(nsIFile *
     if (!newCookie) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     
     // trick: preserve the most-recently-used cookie ordering,
     // by successively decrementing the lastAccessed time
     lastAccessedCounter--;
 
-    if (originalCookieCount == 0) {
-      AddCookieToList(baseDomain, newCookie, paramsArray);
-    }
-    else {
-      AddInternal(baseDomain, newCookie, currentTimeInUsec, NULL, NULL, PR_TRUE,
-                  paramsArray);
-    }
+    if (originalCookieCount == 0)
+      AddCookieToList(baseDomain, newCookie);
+    else
+      AddInternal(baseDomain, newCookie, currentTimeInUsec, nsnull, nsnull, PR_TRUE);
   }
 
-  // If we had a params array, go ahead and write it out to disk now.
-  if (paramsArray) {
-    rv = mDBState->stmtInsert->BindParameters(paramsArray);
-    NS_ASSERT_SUCCESS(rv);
-    nsCOMPtr<mozIStoragePendingStatement> handle;
-    rv = mDBState->stmtInsert->ExecuteAsync(&sInsertCookieDBListener,
-                                            getter_AddRefs(handle));
-    NS_ASSERT_SUCCESS(rv);
-  }
-
-
   COOKIE_LOGSTRING(PR_LOG_DEBUG, ("ImportCookies(): %ld cookies imported", mDBState->cookieCount));
 
   return NS_OK;
 }
 
 /******************************************************************************
  * nsCookieService impl:
  * private GetCookie/SetCookie helpers
@@ -1595,36 +1442,25 @@ nsCookieService::GetCookieInternal(nsIUR
 
   PRInt32 count = foundCookieList.Length();
   if (count == 0)
     return;
 
   // update lastAccessed timestamps. we only do this if the timestamp is stale
   // by a certain amount, to avoid thrashing the db during pageload.
   if (stale) {
-    // Create an array of parameters to bind to our update statement.
-    nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
-    mozIStorageStatement* stmt = mDBState->stmtUpdate;
-    if (mDBState->dbConn) {
-      stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
-    }
+    // start a transaction on the storage db, to optimize updates.
+    // transaction will automically commit on completion.
+    mozStorageTransaction transaction(mDBState->dbConn, PR_TRUE);
 
     for (PRInt32 i = 0; i < count; ++i) {
       cookie = foundCookieList.ElementAt(i);
 
       if (currentTimeInUsec - cookie->LastAccessed() > kCookieStaleThreshold)
-        UpdateCookieInList(cookie, currentTimeInUsec, paramsArray);
-    }
-    // Update the database now if we had a parameters array.
-    if (paramsArray) {
-      nsresult rv = stmt->BindParameters(paramsArray);
-      NS_ASSERT_SUCCESS(rv);
-      nsCOMPtr<mozIStoragePendingStatement> handle;
-      rv = stmt->ExecuteAsync(&sUpdateCookieDBListener, getter_AddRefs(handle));
-      NS_ASSERT_SUCCESS(rv);
+        UpdateCookieInList(cookie, currentTimeInUsec);
     }
   }
 
   // return cookies in order of path length; longest to shortest.
   // this is required per RFC2109.  if cookies match in length,
   // then sort by creation time (see bug 236772).
   foundCookieList.Sort(CompareCookiesForSending());
 
@@ -1656,24 +1492,23 @@ nsCookieService::GetCookieInternal(nsIUR
     COOKIE_LOGSUCCESS(GET_COOKIE, aHostURI, cookieData, nsnull, nsnull);
     *aCookie = ToNewCString(cookieData);
   }
 }
 
 // processes a single cookie, and returns PR_TRUE if there are more cookies
 // to be processed
 PRBool
-nsCookieService::SetCookieInternal(nsIURI                        *aHostURI,
-                                   nsIChannel                    *aChannel,
-                                   const nsCString               &aBaseDomain,
-                                   PRBool                         aRequireHostMatch,
-                                   nsDependentCString            &aCookieHeader,
-                                   PRInt64                        aServerTime,
-                                   PRBool                         aFromHttp,
-                                   mozIStorageBindingParamsArray *aParamsArray)
+nsCookieService::SetCookieInternal(nsIURI             *aHostURI,
+                                   nsIChannel         *aChannel,
+                                   const nsCString    &aBaseDomain,
+                                   PRBool              aRequireHostMatch,
+                                   nsDependentCString &aCookieHeader,
+                                   PRInt64             aServerTime,
+                                   PRBool              aFromHttp)
 {
   // create a stack-based nsCookieAttributes, to store all the
   // attributes parsed from the cookie
   nsCookieAttributes cookieAttributes;
 
   // init expiryTime such that session cookies won't prematurely expire
   cookieAttributes.expiryTime = LL_MAXINT;
 
@@ -1748,42 +1583,46 @@ nsCookieService::SetCookieInternal(nsIUR
     // update isSession and expiry attributes, in case they changed
     cookie->SetIsSession(cookieAttributes.isSession);
     cookie->SetExpiry(cookieAttributes.expiryTime);
   }
 
   // add the cookie to the list. AddInternal() takes care of logging.
   // we get the current time again here, since it may have changed during prompting
   AddInternal(aBaseDomain, cookie, PR_Now(), aHostURI, savedCookieHeader.get(),
-              aFromHttp, aParamsArray);
+              aFromHttp);
   return newCookie;
 }
 
 // this is a backend function for adding a cookie to the list, via SetCookie.
 // also used in the cookie manager, for profile migration from IE.
 // it either replaces an existing cookie; or adds the cookie to the hashtable,
 // and deletes a cookie (if maximum number of cookies has been
 // reached). also performs list maintenance by removing expired cookies.
 void
-nsCookieService::AddInternal(const nsCString               &aBaseDomain,
-                             nsCookie                      *aCookie,
-                             PRInt64                        aCurrentTimeInUsec,
-                             nsIURI                        *aHostURI,
-                             const char                    *aCookieHeader,
-                             PRBool                         aFromHttp,
-                             mozIStorageBindingParamsArray *aParamsArray)
+nsCookieService::AddInternal(const nsCString &aBaseDomain,
+                             nsCookie        *aCookie,
+                             PRInt64          aCurrentTimeInUsec,
+                             nsIURI          *aHostURI,
+                             const char      *aCookieHeader,
+                             PRBool           aFromHttp)
 {
   PRInt64 currentTime = aCurrentTimeInUsec / PR_USEC_PER_SEC;
 
   // if the new cookie is httponly, make sure we're not coming from script
   if (!aFromHttp && aCookie->IsHttpOnly()) {
     COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, "cookie is httponly; coming from script");
     return;
   }
 
+  // start a transaction on the storage db, to optimize deletions/insertions.
+  // transaction will automically commit on completion. if we already have a
+  // transaction (e.g. from SetCookie*()), this will have no effect. 
+  mozStorageTransaction transaction(mDBState->dbConn, PR_TRUE);
+
   nsListIter matchIter;
   PRBool foundCookie = FindCookie(aBaseDomain, aCookie->Host(),
     aCookie->Name(), aCookie->Path(), matchIter, currentTime);
 
   nsRefPtr<nsCookie> oldCookie;
   if (foundCookie) {
     oldCookie = matchIter.Cookie();
 
@@ -1834,17 +1673,17 @@ nsCookieService::AddInternal(const nsCSt
         // note that the cookieOldestTime indicator can be pessimistic - if it's
         // older than the actual oldest cookie, we'll just purge more eagerly.
         PurgeCookies(aCurrentTimeInUsec);
       }
     }
   }
 
   // add the cookie to head of list
-  AddCookieToList(aBaseDomain, aCookie, aParamsArray);
+  AddCookieToList(aBaseDomain, aCookie);
   NotifyChanged(aCookie, foundCookie ? NS_LITERAL_STRING("changed").get()
                                      : NS_LITERAL_STRING("added").get());
 
   COOKIE_LOGSUCCESS(SET_COOKIE, aHostURI, aCookieHeader, aCookie, foundCookie != nsnull);
 }
 
 /******************************************************************************
  * nsCookieService impl:
@@ -2438,44 +2277,37 @@ nsCookieService::RemoveAllFromMemory()
 // since enumeration is done using callback functions
 struct nsPurgeData
 {
   typedef nsTArray<nsListIter> ArrayType;
 
   nsPurgeData(PRInt64 aCurrentTime,
               PRInt64 aPurgeTime,
               ArrayType &aPurgeList,
-              nsIMutableArray *aRemovedList,
-              mozIStorageBindingParamsArray *aParamsArray)
+              nsIMutableArray *aRemovedList)
    : currentTime(aCurrentTime)
    , purgeTime(aPurgeTime)
    , oldestTime(LL_MAXINT)
    , purgeList(aPurgeList)
-   , removedList(aRemovedList)
-   , paramsArray(aParamsArray)
-  {
-  }
+   , removedList(aRemovedList) {}
 
   // the current time, in seconds
   PRInt64 currentTime;
 
   // lastAccessed time older than which cookies are eligible for purge
   PRInt64 purgeTime;
 
   // lastAccessed time of the oldest cookie found during purge, to update our indicator
   PRInt64 oldestTime;
 
   // list of cookies over the age limit, for purging
   ArrayType &purgeList;
 
   // list of all cookies we've removed, for notification
   nsIMutableArray *removedList;
-
-  // The array of parameters to be bound to the statement for deletion later.
-  mozIStorageBindingParamsArray *paramsArray;
 };
 
 // comparator class for lastaccessed times of cookies.
 class CompareCookiesByAge {
 public:
   PRBool Equals(const nsListIter &a, const nsListIter &b) const
   {
     // CreationID is unique, so two id's can never be equal.
@@ -2513,28 +2345,27 @@ public:
 
 PLDHashOperator
 purgeCookiesCallback(nsCookieEntry *aEntry,
                      void          *aArg)
 {
   nsPurgeData &data = *static_cast<nsPurgeData*>(aArg);
 
   const nsCookieEntry::ArrayType &cookies = aEntry->GetCookies();
-  mozIStorageBindingParamsArray *array = data.paramsArray;
   for (nsCookieEntry::IndexType i = 0; i < cookies.Length(); ) {
     nsListIter iter(aEntry, i);
     nsCookie *cookie = cookies[i];
 
     // check if the cookie has expired
     if (cookie->Expiry() <= data.currentTime) {
       data.removedList->AppendElement(cookie, PR_FALSE);
       COOKIE_LOGEVICTED(cookie);
 
       // remove from list; do not increment our iterator
-      nsCookieService::gCookieService->RemoveCookieFromList(iter, array);
+      nsCookieService::gCookieService->RemoveCookieFromList(iter);
 
     } else {
       // check if the cookie is over the age limit
       if (cookie->LastAccessed() <= data.purgeTime) {
         data.purgeList.AppendElement(iter);
 
       } else if (cookie->LastAccessed() < data.oldestTime) {
         // reset our indicator
@@ -2560,24 +2391,18 @@ nsCookieService::PurgeCookies(PRInt64 aC
 #endif
 
   nsAutoTArray<nsListIter, kMaxNumberOfCookies> purgeList;
 
   nsCOMPtr<nsIMutableArray> removedList = do_CreateInstance(NS_ARRAY_CONTRACTID);
   if (!removedList)
     return;
 
-  mozIStorageStatement *stmt = mDBState->stmtDelete;
-  nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
-  if (mDBState->dbConn) {
-    stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
-  }
-
   nsPurgeData data(aCurrentTimeInUsec / PR_USEC_PER_SEC,
-    aCurrentTimeInUsec - mCookiePurgeAge, purgeList, removedList, paramsArray);
+    aCurrentTimeInUsec - mCookiePurgeAge, purgeList, removedList);
   mDBState->hostTable.EnumerateEntries(purgeCookiesCallback, &data);
 
 #ifdef PR_LOGGING
   PRUint32 postExpiryCookieCount = mDBState->cookieCount;
 #endif
 
   // now we have a list of iterators for cookies over the age limit.
   // sort them by age, and then we'll see how many to remove...
@@ -2596,25 +2421,17 @@ nsCookieService::PurgeCookies(PRInt64 aC
   // together, and with ascending index. this allows us to iterate backwards
   // over the list removing cookies, without having to adjust indexes as we go.
   purgeList.Sort(CompareCookiesByIndex());
   for (nsPurgeData::ArrayType::index_type i = purgeList.Length(); i--; ) {
     nsCookie *cookie = purgeList[i].Cookie();
     removedList->AppendElement(cookie, PR_FALSE);
     COOKIE_LOGEVICTED(cookie);
 
-    RemoveCookieFromList(purgeList[i], paramsArray);
-  }
-
-  if (paramsArray) {
-    nsresult rv = stmt->BindParameters(paramsArray);
-    NS_ASSERT_SUCCESS(rv);
-    nsCOMPtr<mozIStoragePendingStatement> handle;
-    rv = stmt->ExecuteAsync(&sRemoveCookieDBListener, getter_AddRefs(handle));
-    NS_ASSERT_SUCCESS(rv);
+    RemoveCookieFromList(purgeList[i]);
   }
 
   // take all the cookies in the removed list, and notify about them in one batch
   NotifyChanged(removedList, NS_LITERAL_STRING("batch-deleted").get());
 
   // reset the oldest time indicator
   mDBState->cookieOldestTime = data.oldestTime;
 
@@ -2763,46 +2580,33 @@ nsCookieService::FindCookie(const nsCStr
     }
   }
 
   return PR_FALSE;
 }
 
 // remove a cookie from the hashtable, and update the iterator state.
 void
-nsCookieService::RemoveCookieFromList(const nsListIter              &aIter,
-                                      mozIStorageBindingParamsArray *aParamsArray)
+nsCookieService::RemoveCookieFromList(const nsListIter &aIter)
 {
   // if it's a non-session cookie, remove it from the db
   if (!aIter.Cookie()->IsSession() && mDBState->dbConn) {
-    // Use the asynchronous binding methods to ensure that we do not acquire
-    // the database lock.
-    mozIStorageStatement *stmt = mDBState->stmtDelete;
-    nsCOMPtr<mozIStorageBindingParamsArray> paramsArray(aParamsArray);
-    if (!paramsArray) {
-      stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
+    // use our cached sqlite "delete" statement
+    mozStorageStatementScoper scoper(mDBState->stmtDelete);
+
+    PRInt64 creationID = aIter.Cookie()->CreationID();
+    nsresult rv = mDBState->stmtDelete->BindInt64Parameter(0, creationID);
+    if (NS_SUCCEEDED(rv)) {
+      PRBool hasResult;
+      rv = mDBState->stmtDelete->ExecuteStep(&hasResult);
     }
 
-    nsCOMPtr<mozIStorageBindingParams> params;
-    paramsArray->NewBindingParams(getter_AddRefs(params));
-
-    nsresult rv = params->BindInt64ByIndex(0, aIter.Cookie()->CreationID());
-    NS_ASSERT_SUCCESS(rv);
-
-    rv = paramsArray->AddParams(params);
-    NS_ASSERT_SUCCESS(rv);
-
-    // If we weren't given a params array, we'll need to remove it ourselves.
-    if (!aParamsArray) {
-      rv = stmt->BindParameters(paramsArray);
-      NS_ASSERT_SUCCESS(rv);
-      nsCOMPtr<mozIStoragePendingStatement> handle;
-      rv = stmt->ExecuteAsync(&sRemoveCookieDBListener,
-                              getter_AddRefs(handle));
-      NS_ASSERT_SUCCESS(rv);
+    if (NS_FAILED(rv)) {
+      NS_WARNING("db remove failed!");
+      COOKIE_LOGSTRING(PR_LOG_WARNING, ("RemoveCookieFromList(): removing from db gave error %x", rv));
     }
   }
 
   if (aIter.entry->GetCookies().Length() == 1) {
     // we're removing the last element in the array - so just remove the entry
     // from the hash. note that the entryclass' dtor will take care of
     // releasing this last element for us!
     mDBState->hostTable.RawRemoveEntry(aIter.entry);
@@ -2810,127 +2614,106 @@ nsCookieService::RemoveCookieFromList(co
   } else {
     // just remove the element from the list
     aIter.entry->GetCookies().RemoveElementAt(aIter.index);
   }
 
   --mDBState->cookieCount;
 }
 
-static void
-bindCookieParameters(mozIStorageBindingParamsArray *aParamsArray,
-                     const nsCookie *aCookie)
+static nsresult
+bindCookieParameters(mozIStorageStatement *aStmt, const nsCookie *aCookie)
 {
-  NS_ASSERTION(aParamsArray, "Null params array passed to bindCookieParameters!");
-  NS_ASSERTION(aCookie, "Null cookie passed to bindCookieParameters!");
   nsresult rv;
 
-  // Use the asynchronous binding methods to ensure that we do not acquire the
-  // database lock.
-  nsCOMPtr<mozIStorageBindingParams> params;
-  rv = aParamsArray->NewBindingParams(getter_AddRefs(params));
-  NS_ASSERT_SUCCESS(rv);
-
-  // Bind our values to params
-  rv = params->BindInt64ByIndex(0, aCookie->CreationID());
-  NS_ASSERT_SUCCESS(rv);
-
-  rv = params->BindUTF8StringByIndex(1, aCookie->Name());
-  NS_ASSERT_SUCCESS(rv);
-
-  rv = params->BindUTF8StringByIndex(2, aCookie->Value());
-  NS_ASSERT_SUCCESS(rv);
-
-  rv = params->BindUTF8StringByIndex(3, aCookie->Host());
-  NS_ASSERT_SUCCESS(rv);
-
-  rv = params->BindUTF8StringByIndex(4, aCookie->Path());
-  NS_ASSERT_SUCCESS(rv);
-
-  rv = params->BindInt64ByIndex(5, aCookie->Expiry());
-  NS_ASSERT_SUCCESS(rv);
-
-  rv = params->BindInt64ByIndex(6, aCookie->LastAccessed());
-  NS_ASSERT_SUCCESS(rv);
-
-  rv = params->BindInt32ByIndex(7, aCookie->IsSecure());
-  NS_ASSERT_SUCCESS(rv);
-
-  rv = params->BindInt32ByIndex(8, aCookie->IsHttpOnly());
-  NS_ASSERT_SUCCESS(rv);
-
-  // Bind the params to the array.
-  rv = aParamsArray->AddParams(params);
-  NS_ASSERT_SUCCESS(rv);
+  rv = aStmt->BindInt64Parameter(0, aCookie->CreationID());
+  if (NS_FAILED(rv)) return rv;
+
+  rv = aStmt->BindUTF8StringParameter(1, aCookie->Name());
+  if (NS_FAILED(rv)) return rv;
+  
+  rv = aStmt->BindUTF8StringParameter(2, aCookie->Value());
+  if (NS_FAILED(rv)) return rv;
+  
+  rv = aStmt->BindUTF8StringParameter(3, aCookie->Host());
+  if (NS_FAILED(rv)) return rv;
+  
+  rv = aStmt->BindUTF8StringParameter(4, aCookie->Path());
+  if (NS_FAILED(rv)) return rv;
+  
+  rv = aStmt->BindInt64Parameter(5, aCookie->Expiry());
+  if (NS_FAILED(rv)) return rv;
+  
+  rv = aStmt->BindInt64Parameter(6, aCookie->LastAccessed());
+  if (NS_FAILED(rv)) return rv;
+  
+  rv = aStmt->BindInt32Parameter(7, aCookie->IsSecure());
+  if (NS_FAILED(rv)) return rv;
+  
+  rv = aStmt->BindInt32Parameter(8, aCookie->IsHttpOnly());
+  return rv;
 }
 
 PRBool
-nsCookieService::AddCookieToList(const nsCString               &aBaseDomain,
-                                 nsCookie                      *aCookie,
-                                 mozIStorageBindingParamsArray *aParamsArray,
-                                 PRBool                         aWriteToDB)
+nsCookieService::AddCookieToList(const nsCString &aBaseDomain,
+                                 nsCookie        *aCookie,
+                                 PRBool           aWriteToDB)
 {
-  NS_ASSERTION(!(mDBState->dbConn && !aWriteToDB && aParamsArray),
-               "Not writing to the DB but have a params array?");
-  NS_ASSERTION(!(!mDBState->dbConn && aParamsArray),
-               "Do not have a DB connection but have a params array?");
-
   nsCookieEntry *entry = mDBState->hostTable.PutEntry(aBaseDomain);
   if (!entry) {
     NS_ERROR("can't insert element into a null entry!");
     return PR_FALSE;
   }
 
   entry->GetCookies().AppendElement(aCookie);
   ++mDBState->cookieCount;
 
   // keep track of the oldest cookie, for when it comes time to purge
   if (aCookie->LastAccessed() < mDBState->cookieOldestTime)
     mDBState->cookieOldestTime = aCookie->LastAccessed();
 
   // if it's a non-session cookie and hasn't just been read from the db, write it out.
   if (aWriteToDB && !aCookie->IsSession() && mDBState->dbConn) {
-    nsCOMPtr<mozIStorageBindingParamsArray> array(aParamsArray);
-    if (!array) {
-      mDBState->stmtInsert->NewBindingParamsArray(getter_AddRefs(array));
+    // use our cached sqlite "insert" statement
+    mozStorageStatementScoper scoper(mDBState->stmtInsert);
+
+    nsresult rv = bindCookieParameters(mDBState->stmtInsert, aCookie);
+    if (NS_SUCCEEDED(rv)) {
+      PRBool hasResult;
+      rv = mDBState->stmtInsert->ExecuteStep(&hasResult);
     }
-    bindCookieParameters(array, aCookie);
-
-    // If we were supplied an array to store parameters, we shouldn't call
-    // executeAsync - someone up the stack will do this for us.
-    if (!aParamsArray) {
-      nsCOMPtr<mozIStoragePendingStatement> handle;
-      nsresult rv = mDBState->stmtInsert->ExecuteAsync(&sInsertCookieDBListener,
-                                                       getter_AddRefs(handle));
-      NS_ASSERT_SUCCESS(rv);
+
+    if (NS_FAILED(rv)) {
+      NS_WARNING("db insert failed!");
+      COOKIE_LOGSTRING(PR_LOG_WARNING, ("AddCookieToList(): adding to db gave error %x", rv));
     }
   }
 
   return PR_TRUE;
 }
 
 void
-nsCookieService::UpdateCookieInList(nsCookie                      *aCookie,
-                                    PRInt64                        aLastAccessed,
-                                    mozIStorageBindingParamsArray *aParamsArray)
+nsCookieService::UpdateCookieInList(nsCookie *aCookie, PRInt64 aLastAccessed)
 {
-  NS_ASSERTION(aCookie, "Passing a null cookie to UpdateCookieInList!");
-
-  // udpate the lastAccessed timestamp
+  // update the lastAccessed timestamp
   aCookie->SetLastAccessed(aLastAccessed);
 
   // if it's a non-session cookie, update it in the db too
-  if (!aCookie->IsSession() && aParamsArray) {
-    // Create our params holder.
-    nsCOMPtr<mozIStorageBindingParams> params;
-    aParamsArray->NewBindingParams(getter_AddRefs(params));
-
-    // Bind our parameters.
-    nsresult rv = params->BindInt64ByIndex(0, aLastAccessed);
-    NS_ASSERT_SUCCESS(rv);
-    rv = params->BindInt64ByIndex(1, aCookie->CreationID());
-    NS_ASSERT_SUCCESS(rv);
-
-    // Add our bound parameters to the array.
-    rv = aParamsArray->AddParams(params);
-    NS_ASSERT_SUCCESS(rv);
+  if (!aCookie->IsSession() && mDBState->dbConn) {
+    // use our cached sqlite "update" statement
+    mozStorageStatementScoper scoper(mDBState->stmtUpdate);
+
+    nsresult rv = mDBState->stmtUpdate->BindInt64Parameter(0, aLastAccessed);
+    if (NS_SUCCEEDED(rv)) {
+      rv = mDBState->stmtUpdate->BindInt64Parameter(1, aCookie->CreationID());
+      if (NS_SUCCEEDED(rv)) {
+        PRBool hasResult;
+        rv = mDBState->stmtUpdate->ExecuteStep(&hasResult);
+      }
+    }
+
+    if (NS_FAILED(rv)) {
+      NS_WARNING("db update failed!");
+      COOKIE_LOGSTRING(PR_LOG_WARNING, ("UpdateCookieInList(): updating db gave error %x", rv));
+    }
   }
 }
+
--- a/netwerk/cookie/src/nsCookieService.h
+++ b/netwerk/cookie/src/nsCookieService.h
@@ -169,21 +169,21 @@ class nsCookieService : public nsICookie
     nsresult                      CreateTable();
     void                          CloseDB();
     nsresult                      Read();
     nsresult                      NormalizeHost(nsCString &aHost);
     nsresult                      GetBaseDomain(nsIURI *aHostURI, nsCString &aBaseDomain, PRBool &aRequireHostMatch);
     nsresult                      GetBaseDomainFromHost(const nsACString &aHost, nsCString &aBaseDomain);
     void                          GetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, PRBool aHttpBound, char **aCookie);
     nsresult                      SetCookieStringInternal(nsIURI *aHostURI, nsIPrompt *aPrompt, const char *aCookieHeader, const char *aServerTime, nsIChannel *aChannel, PRBool aFromHttp);
-    PRBool                        SetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, const nsCString& aBaseDomain, PRBool aRequireHostMatch, nsDependentCString &aCookieHeader, PRInt64 aServerTime, PRBool aFromHttp, mozIStorageBindingParamsArray *aParamsArray = NULL);
-    void                          AddInternal(const nsCString& aBaseDomain, nsCookie *aCookie, PRInt64 aCurrentTimeInUsec, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp, mozIStorageBindingParamsArray *aParamsArray = NULL);
-    void                          RemoveCookieFromList(const nsListIter &aIter, mozIStorageBindingParamsArray *aParamsArray = NULL);
-    PRBool                        AddCookieToList(const nsCString& aBaseDomain, nsCookie *aCookie, mozIStorageBindingParamsArray *aParamsArray, PRBool aWriteToDB = PR_TRUE);
-    void                          UpdateCookieInList(nsCookie *aCookie, PRInt64 aLastAccessed, mozIStorageBindingParamsArray *aParamsArray);
+    PRBool                        SetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, const nsCString& aBaseDomain, PRBool aRequireHostMatch, nsDependentCString &aCookieHeader, PRInt64 aServerTime, PRBool aFromHttp);
+    void                          AddInternal(const nsCString& aBaseDomain, nsCookie *aCookie, PRInt64 aCurrentTimeInUsec, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp);
+    void                          RemoveCookieFromList(const nsListIter &aIter);
+    PRBool                        AddCookieToList(const nsCString& aBaseDomain, nsCookie *aCookie, PRBool aWriteToDB = PR_TRUE);
+    void                          UpdateCookieInList(nsCookie *aCookie, PRInt64 aLastAccessed);
     static PRBool                 GetTokenValue(nsASingleFragmentCString::const_char_iterator &aIter, nsASingleFragmentCString::const_char_iterator &aEndIter, nsDependentCSubstring &aTokenString, nsDependentCSubstring &aTokenValue, PRBool &aEqualsFound);
     static PRBool                 ParseAttributes(nsDependentCString &aCookieHeader, nsCookieAttributes &aCookie);
     PRBool                        IsForeign(const nsCString &aBaseDomain, PRBool aRequireHostMatch, nsIURI *aFirstURI);
     PRUint32                      CheckPrefs(nsIURI *aHostURI, nsIChannel *aChannel, const nsCString &aBaseDomain, PRBool aRequireHostMatch, const char *aCookieHeader);
     PRBool                        CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI, const nsCString &aBaseDomain, PRBool aRequireHostMatch);
     static PRBool                 CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI);
     static PRBool                 GetExpiry(nsCookieAttributes &aCookie, PRInt64 aServerTime, PRInt64 aCurrentTime);
     void                          RemoveAllFromMemory();
--- a/storage/public/storage.h
+++ b/storage/public/storage.h
@@ -38,31 +38,29 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_storage_h_
 #define mozilla_storage_h_
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Public Interfaces
 
-#include "mozStorageCID.h"
 #include "mozIStorageAggregateFunction.h"
 #include "mozIStorageConnection.h"
 #include "mozIStorageError.h"
 #include "mozIStorageFunction.h"
 #include "mozIStoragePendingStatement.h"
 #include "mozIStorageProgressHandler.h"
 #include "mozIStorageResultSet.h"
 #include "mozIStorageRow.h"
 #include "mozIStorageService.h"
 #include "mozIStorageStatement.h"
 #include "mozIStorageStatementCallback.h"
-#include "mozIStorageBindingParamsArray.h"
-#include "mozIStorageBindingParams.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Native Language Helpers
 
 #include "mozStorageHelper.h"
+#include "mozStorageCID.h"
 
 #include "mozilla/storage/Variant.h"
 
 #endif // mozilla_storage_h_