Bug 1630176 - Fix the race between process switching and the new browser window loading code, r=kmag
authorAnny Gakhokidze <agakhokidze@mozilla.com>
Tue, 30 Jun 2020 20:57:52 +0000
changeset 538121 f0e47b29f8c4840d9f9fbe971991f86179b55314
parent 538120 e10c6c54d4b62d53289112d7754085aa1581c635
child 538122 9e5effc60b13d3531f529d06d7e76e0da5701185
push id37557
push userabutkovits@mozilla.com
push dateWed, 01 Jul 2020 03:27:11 +0000
treeherdermozilla-central@f0e47b29f8c4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1630176
milestone80.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1630176 - Fix the race between process switching and the new browser window loading code, r=kmag Differential Revision: https://phabricator.services.mozilla.com/D81563
browser/components/sessionstore/SessionStore.jsm
browser/components/sessionstore/TabStateFlusher.jsm
dom/serviceworkers/test/mochitest.ini
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -454,16 +454,32 @@ var SessionStore = {
     return SessionStoreInternal.undoCloseById(aClosedId, aIncludePrivate);
   },
 
   resetBrowserToLazyState(tab) {
     return SessionStoreInternal.resetBrowserToLazyState(tab);
   },
 
   /**
+   * Ensures that session store has registered and started tracking a given window.
+   * @param window
+   *        Window reference
+   */
+  ensureInitialized(window) {
+    if (SessionStoreInternal._sessionInitialized && !window.__SSi) {
+      /*
+        We need to check that __SSi is not defined on the window so that if
+        onLoad function is in the middle of executing we don't enter the function
+        again and try to redeclare the ContentSessionStore script.
+       */
+      SessionStoreInternal.onLoad(window);
+    }
+  },
+
+  /**
    * Determines whether the passed version number is compatible with
    * the current version number of the SessionStore.
    *
    * @param version The format and version of the file, as an array, e.g.
    * ["sessionrestore", 1]
    */
   isFormatVersionCompatible(version) {
     if (!version) {
--- a/browser/components/sessionstore/TabStateFlusher.jsm
+++ b/browser/components/sessionstore/TabStateFlusher.jsm
@@ -1,16 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["TabStateFlusher"];
 
+ChromeUtils.defineModuleGetter(
+  this,
+  "SessionStore",
+  "resource:///modules/sessionstore/SessionStore.jsm"
+);
+
 /**
  * A module that enables async flushes. Updates from frame scripts are
  * throttled to be sent only once per second. If an action wants a tab's latest
  * state without waiting for a second then it can request an async flush and
  * wait until the frame scripts reported back. At this point the parent has the
  * latest data and the action can continue.
  */
 var TabStateFlusher = Object.freeze({
@@ -87,16 +93,25 @@ var TabStateFlusherInternal = {
     let requestNativeListener = false;
     if (browser && browser.frameLoader) {
       /*
         Request native listener to flush the tabState.
         True if the flush is involved async ipc call.
        */
       requestNativeListener = browser.frameLoader.requestTabStateFlush(id);
     }
+    /*
+      In the event that we have to trigger a process switch and thus change
+      browser remoteness, session store needs to register and track the new
+      browser window loaded and to have message manager listener registered
+      ** before ** TabStateFlusher send "SessionStore:flush" message. This fixes
+      the race where we send the message before the message listener is
+      registered for it.
+      */
+    SessionStore.ensureInitialized(browser.ownerGlobal);
 
     let mm = browser.messageManager;
     mm.sendAsyncMessage("SessionStore:flush", { id });
 
     // Retrieve active requests for given browser.
     let permanentKey = browser.permanentKey;
     let perBrowserRequests = this._requests.get(permanentKey) || new Map();
     let perBrowserRequestsToNative =
--- a/dom/serviceworkers/test/mochitest.ini
+++ b/dom/serviceworkers/test/mochitest.ini
@@ -283,17 +283,17 @@ skip-if = toolkit == 'android' && !is_fe
 [test_match_all_client_properties.html]
 skip-if = toolkit == 'android' && !is_fennec
 [test_navigator.html]
 [test_not_intercept_plugin.html]
 skip-if = serviceworker_e10s # leaks InterceptedHttpChannel and others things
 [test_notification_constructor_error.html]
 [test_notification_get.html]
 [test_notification_openWindow.html]
-skip-if = toolkit == 'android' && !is_fennec || (os == "linux" && bits == 64) || (os == "win" && !debug && bits == 64) # Bug 1620052
+skip-if = toolkit == 'android' && !is_fennec # Bug 1620052
   || xorigin # JavaScript error: http://mochi.xorigin-test:8888/tests/SimpleTest/TestRunner.js, line 157: SecurityError: Permission denied to access property "wrappedJSObject" on cross-origin object
 support-files = notification_openWindow_worker.js file_notification_openWindow.html
 tags = openwindow
 [test_notificationclick.html]
 [test_notificationclick_focus.html]
 [test_notificationclick-otherwindow.html]
 [test_notificationclose.html]
 [test_onmessageerror.html]