Bug 1041788 - Don't enter _beginRemoveTab() when a .permitUnload() call is pending r=dao a=sylvestre
authorTim Taubert <ttaubert@mozilla.com>
Wed, 30 Jul 2014 11:59:56 +0200
changeset 208223 faf3b10d4868
parent 208222 a59d3af0c000
child 208224 91dca763d0f5
push id3781
push userttaubert@mozilla.com
push date2014-08-04 14:17 +0000
treeherdermozilla-beta@faf3b10d4868 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao, sylvestre
bugs1041788
milestone32.0
Bug 1041788 - Don't enter _beginRemoveTab() when a .permitUnload() call is pending r=dao a=sylvestre
browser/base/content/tabbrowser.xml
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1890,27 +1890,35 @@
       <method name="_beginRemoveTab">
         <parameter name="aTab"/>
         <parameter name="aTabWillBeMoved"/>
         <parameter name="aCloseWindowWithLastTab"/>
         <parameter name="aCloseWindowFastpath"/>
         <body>
           <![CDATA[
             if (aTab.closing ||
+                aTab._pendingPermitUnload ||
                 this._windowIsClosing)
               return false;
 
             var browser = this.getBrowserForTab(aTab);
 
             if (!aTabWillBeMoved) {
               let ds = browser.docShell;
-              if (ds &&
-                  ds.contentViewer &&
-                  !ds.contentViewer.permitUnload()) {
-                return false;
+              if (ds && ds.contentViewer) {
+                // We need to block while calling permitUnload() because it
+                // processes the event queue and may lead to another removeTab()
+                // call before permitUnload() even returned.
+                aTab._pendingPermitUnload = true;
+                let permitUnload = ds.contentViewer.permitUnload();
+                delete aTab._pendingPermitUnload;
+
+                if (!permitUnload) {
+                  return false;
+                }
               }
             }
 
             var closeWindow = false;
             var newTab = false;
             if (this.tabs.length - this._removingTabs.length == 1) {
               closeWindow = aCloseWindowWithLastTab != null ? aCloseWindowWithLastTab :
                             !window.toolbar.visible ||