Bug 928630 - Wait for the initial window's delayed startup to be finished before restoring a session; r=smacleod
authorTim Taubert <ttaubert@mozilla.com>
Wed, 23 Oct 2013 19:05:41 +0200
changeset 166577 b185e2dd95d49dc60a82173b173726c198de78f6
parent 166576 69ebfb936442e2c08c41b281d7a8eb65f0210c9c
child 166578 70e1e02b917ddca12f258ceb7fb7f8773900066c
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmacleod
bugs928630
milestone27.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 928630 - Wait for the initial window's delayed startup to be finished before restoring a session; r=smacleod
browser/components/sessionstore/src/SessionStore.jsm
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -345,16 +345,20 @@ let SessionStoreInternal = {
 
   // Whether session has been initialized
   _sessionInitialized: false,
 
   // True if session store is disabled by multi-process browsing.
   // See bug 516755.
   _disabledForMultiProcess: false,
 
+  // Promise that is resolved when we're ready to initialize
+  // and restore the session.
+  _promiseReadyForInitialization: null,
+
   /**
    * A promise fulfilled once initialization is complete.
    */
   get promiseInitialized() {
     return this._deferredInitialized.promise;
   },
 
   /* ........ Public Getters .............. */
@@ -865,23 +869,43 @@ let SessionStoreInternal = {
         return;
       }
 
       if (this._sessionInitialized) {
         this.onLoad(aWindow);
         return;
       }
 
+      // The very first window that is opened creates a promise that is then
+      // re-used by all subsequent windows. The promise will be used to tell
+      // when we're ready for initialization.
+      if (!this._promiseReadyForInitialization) {
+        let deferred = Promise.defer();
+
+        // Wait for the given window's delayed startup to be finished.
+        Services.obs.addObserver(function obs(subject, topic) {
+          if (aWindow == subject) {
+            Services.obs.removeObserver(obs, topic);
+            deferred.resolve();
+          }
+        }, "browser-delayed-startup-finished", false);
+
+        // We are ready for initialization as soon as the session file has been
+        // read from disk and the initial window's delayed startup has finished.
+        this._promiseReadyForInitialization =
+          Promise.all([deferred.promise, gSessionStartup.onceInitialized]);
+      }
+
       // We can't call this.onLoad since initialization
       // hasn't completed, so we'll wait until it is done.
       // Even if additional windows are opened and wait
       // for initialization as well, the first opened
       // window should execute first, and this.onLoad
       // will be called with the initialState.
-      gSessionStartup.onceInitialized.then(() => {
+      this._promiseReadyForInitialization.then(() => {
         if (aWindow.closed) {
           return;
         }
 
         if (this._sessionInitialized) {
           this.onLoad(aWindow);
         } else {
           let initialState = this.initSession();