Bug 511965 - Delay Places syncs after results updates, r=sdwilsh
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 21 Aug 2009 22:36:59 +0200
changeset 31986 7515a0b6955b3868c73923d9bc3cfa76a7685a10
parent 31985 c898d15805a592c03ea8b88efca3fce0db3eae37
child 31987 eba5db180e721533f44d631394ac694799622790
push idunknown
push userunknown
push dateunknown
reviewerssdwilsh
bugs511965
milestone1.9.3a1pre
Bug 511965 - Delay Places syncs after results updates, r=sdwilsh
toolkit/components/places/src/nsPlacesDBFlush.js
--- a/toolkit/components/places/src/nsPlacesDBFlush.js
+++ b/toolkit/components/places/src/nsPlacesDBFlush.js
@@ -217,33 +217,33 @@ nsPlacesDBFlush.prototype = {
   onEndUpdateBatch: function DBFlush_onEndUpdateBatch()
   {
     this._inBatchMode = false;
 
     // Restore our timer
     this._timer = this._newTimer();
 
     // We need to sync now
-    this._flushWithQueries([kQuerySyncPlacesId, kQuerySyncHistoryVisitsId]);
+    this._delayedFlushWithQueries([kQuerySyncPlacesId, kQuerySyncHistoryVisitsId]);
   },
 
   onItemAdded: function(aItemId, aParentId, aIndex)
   {
     // Sync only if we added a TYPE_BOOKMARK item.  Note, we want to run the
     // least amount of queries as possible here for performance reasons.
     if (!this._inBatchMode &&
         this._bs.getItemType(aItemId) == this._bs.TYPE_BOOKMARK)
-      this._flushWithQueries([kQuerySyncPlacesId]);
+      this._delayedFlushWithQueries([kQuerySyncPlacesId]);
   },
 
   onItemChanged: function DBFlush_onItemChanged(aItemId, aProperty,
                                                 aIsAnnotationProperty, aValue)
   {
     if (!this._inBatchMode && aProperty == "uri")
-      this._flushWithQueries([kQuerySyncPlacesId]);
+      this._delayedFlushWithQueries([kQuerySyncPlacesId]);
   },
 
   onBeforeItemRemoved: function() { },
   onItemRemoved: function() { },
   onItemVisited: function() { },
   onItemMoved: function() { },
 
   //////////////////////////////////////////////////////////////////////////////
@@ -346,16 +346,32 @@ nsPlacesDBFlush.prototype = {
     for (let i = 0; i < aQueryNames.length; i++)
       statements.push(this._getQuery(aQueryNames[i]));
 
     // Execute sync statements async in a transaction
     this._db.executeAsync(statements, statements.length, this);
   },
 
   /**
+   * Enqueues a flush to the main thread, used in observers to avoid flushing
+   * while the original method is still notifying.
+   */
+  _delayedFlushWithQueries: function DBFlush_delayedflushWithQueries(aQueryNames)
+  {
+    let tm = Cc["@mozilla.org/thread-manager;1"].
+             getService(Ci.nsIThreadManager);
+    let self = this;
+    tm.mainThread.dispatch({
+      run: function() {
+        self._flushWithQueries(aQueryNames);
+      }
+    }, Ci.nsIThread.DISPATCH_NORMAL);
+  },
+
+  /**
    * Finalizes all of our mozIStorageStatements so we can properly close the
    * database.
    */
   _finalizeInternalStatements: function DBFlush_finalizeInternalStatements()
   {
     for each (let stmt in this._cachedStatements)
       if (stmt instanceof Ci.mozIStorageStatement)
         stmt.finalize();