Fix bug 572489 - Cached calendar refresh can cause database table is locked error. r=philipp
authorWolfgang Sourdeau <WSourdeau@Inverse.ca>
Fri, 30 Jul 2010 18:44:27 +0200
changeset 6042 41c0dab1b83a6cd984d0ef7dfb568942cfc4f827
parent 6041 b8f34cb7b0afb2819ead01e3b4676dfaa7aea7bd
child 6043 666c1eefac5c49cc77120a1ca9833d01cd4fdd71
push idunknown
push userunknown
push dateunknown
reviewersphilipp
bugs572489
Fix bug 572489 - Cached calendar refresh can cause database table is locked error. r=philipp
calendar/providers/storage/calStorageCalendar.js
--- a/calendar/providers/storage/calStorageCalendar.js
+++ b/calendar/providers/storage/calStorageCalendar.js
@@ -48,19 +48,16 @@ Components.utils.import("resource://cale
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calAlarmUtils.jsm");
 Components.utils.import("resource://calendar/modules/calStorageUpgrade.jsm");
 Components.utils.import("resource://calendar/modules/calStorageHelpers.jsm");
 
 const USECS_PER_SECOND = 1000000;
 const kCalICalendar = Components.interfaces.calICalendar;
 
-var gTransCount = {};
-var gTransErr = {};
-
 //
 // calStorageCalendar
 //
 
 function calStorageCalendar() {
     this.initProviderBase();
     this.mItemCache = {};
     this.mRecEventCache = {};
@@ -618,18 +615,18 @@ calStorageCalendar.prototype = {
 
     // void getItems( in unsigned long aItemFilter, in unsigned long aCount,
     //                in calIDateTime aRangeStart, in calIDateTime aRangeEnd,
     //                in calIOperationListener aListener );
     getItems: function cSC_getItems(aItemFilter, aCount,
                                     aRangeStart, aRangeEnd, aListener) {
         let this_ = this;
         cal.postPone(function() {
-                this_.getItems_(aItemFilter, aCount, aRangeStart, aRangeEnd, aListener);
-            });
+            this_.getItems_(aItemFilter, aCount, aRangeStart, aRangeEnd, aListener);
+        });
     },
     getItems_: function cSC_getItems_(aItemFilter, aCount,
                                       aRangeStart, aRangeEnd, aListener)
     {
         //var profStartTime = Date.now();
         if (!aListener)
             return;
 
@@ -1795,19 +1792,19 @@ calStorageCalendar.prototype = {
             params[entryname] = null;
             params[entryname + "_tz"] = null;
         }
     },
 
     flushItem: function cSC_flushItem(item, olditem) {
         ASSERT(!item.recurrenceId, "no parent item passed!", true);
 
-        this.acquireTransaction();
         try {
             this.deleteItemById(olditem ? olditem.id : item.id);
+            this.acquireTransaction();
             this.writeItem(item, olditem);
         } catch (e) {
             this.releaseTransaction(e);
             throw e;
         }
         this.releaseTransaction();
 
         this.cacheItem(item);
@@ -2206,67 +2203,35 @@ calStorageCalendar.prototype = {
         this.releaseTransaction();
 
         delete this.mItemCache[aID];
         delete this.mRecEventCache[aID];
         delete this.mRecTodoCache[aID];
     },
 
     /**
-     * Acquire a transaction for this calendar. This begins a transaction if the
-     * transaction count for the given calendar is zero and otherwise reuses the
-     * existing transaction.
+     * Acquire a transaction for this calendar.
      */
     acquireTransaction: function cSC_acquireTransaction() {
-        let calId = this.id;
-        if (!(calId in gTransCount)) {
-            gTransCount[calId] = 0;
-        }
-        if (gTransCount[calId]++ == 0) {
-            this.mDB.beginTransaction();
-        }
+        this.mDB.beginTransaction();
     },
 
     /**
-     * Releases one level of transactions for this calendar. If the transaction
-     * count reaches zero and no error has occurred, the transaction is committed.
-     * Calling this function with an error remembers that an error has occurred,
-     * when the transaction count reaches zero, the transaction is rolled back.
+     * Releases one level of transactions for this calendar.
      *
      * @param err       (optional) If set, the transaction is set to fail when
      *                    the count reaches zero.
      */
     releaseTransaction: function cSC_releaseTransaction(err) {
-        let calId = this.id;
         if (err) {
-            this.logError("releaseTransaction on error", err);
-            gTransErr[calId] = err;
+            cal.ERROR("DB error: " + this.mDB.lastErrorString + "\nexc: " + err);
+            this.mDB.rollbackTransaction();
+        } else {
+            this.mDB.commitTransaction();
         }
-
-        if (gTransCount[calId] > 0) {
-            if (--gTransCount[calId] == 0) {
-                if (gTransErr[calId]) {
-                    this.mDB.rollbackTransaction();
-                    delete gTransErr[calId];
-                } else {
-                    this.mDB.commitTransaction();
-                }
-            }
-        } else {
-            ASSERT(gTransCount[calId] > 0, "unexpected batch count!");
-        }
-    },
-
-    startBatch: function cSC_startBatch() {
-        this.acquireTransaction();
-        this.__proto__.__proto__.startBatch.apply(this, arguments);
-    },
-    endBatch: function cSC_endBatch() {
-        this.releaseTransaction();
-        this.__proto__.__proto__.endBatch.apply(this, arguments);
     },
 
     //
     // calISyncWriteCalendar interface
     //
 
     setMetaData: function cSC_setMetaData(id, value) {