Bug 1192720 - Prevent re-entrancy in event handling in tabbrowser.xml's _switcher. r=billm, a=sledru
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Thu, 13 Aug 2015 16:55:09 +0100
changeset 288862 5c614f699e6b60e6864eabdc7bc5e25d40b10d06
parent 288861 5da240e25d30052604756ba3c49d325c4a0eb491
child 288863 bb1e324928897d6a468acf13191a9785e858df8d
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm, sledru
bugs1192720
milestone42.0a2
Bug 1192720 - Prevent re-entrancy in event handling in tabbrowser.xml's _switcher. r=billm, a=sledru
browser/base/content/tabbrowser.xml
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3076,16 +3076,19 @@
             // removed from the set upon MozAfterPaint.
             maybeVisibleTabs: new Set([this.selectedTab]),
 
             STATE_UNLOADED: 0,
             STATE_LOADING: 1,
             STATE_LOADED: 2,
             STATE_UNLOADING: 3,
 
+            // re-entrancy guard:
+            _processing: false,
+
             getTabState: function(tab) {
               let state = this.tabState.get(tab);
               if (state === undefined) {
                 return this.STATE_UNLOADED;
               }
               return state;
             },
 
@@ -3218,17 +3221,16 @@
                 // This doesn't necessarily exist if we're a new window and haven't switched tabs yet
                 if (this.lastVisibleTab)
                   this.lastVisibleTab._visuallySelected = false;
 
                 this.visibleTab._visuallySelected = true;
               }
 
               this.lastVisibleTab = this.visibleTab;
-
             },
 
             assert: function(cond) {
               if (!cond) {
                 dump("Assertion failure\n" + Error().stack);
                 throw new Error("Assertion failure");
               }
             },
@@ -3429,30 +3431,41 @@
               this.preActions();
 
               clearTimeout(this.unloadTimer);
               this.unloadTimer = setTimeout(() => this.onUnloadTimeout(), this.UNLOAD_DELAY);
 
               this.postActions();
             },
 
-            handleEvent: function(event) {
+            handleEvent: function(event, delayed = false) {
+              if (this._processing) {
+                setTimeout(() => this.handleEvent(event, true), 0);
+                return;
+              }
+              if (delayed && this.tabbrowser._switcher != this) {
+                // if we delayed processing this event, we might be out of date, in which
+                // case we drop the delayed events
+                return;
+              }
+              this._processing = true;
               this.preActions();
 
               if (event.type == "MozLayerTreeReady") {
                 this.onLayersReady(event.originalTarget);
               } if (event.type == "MozAfterPaint") {
                 this.onPaint();
               } else if (event.type == "MozLayerTreeCleared") {
                 this.onLayersCleared(event.originalTarget);
               } else if (event.type == "TabRemotenessChange") {
                 this.onRemotenessChange(event.target);
               }
 
               this.postActions();
+              this._processing = false;
             },
 
             /*
              * Telemetry and Profiler related helpers for recording tab switch
              * timing.
              */
 
             startTabSwitch: function () {