From 06479834b913a081780e145d94ab39f0d4b01941 Mon Sep 17 00:00:00 2001 From: "sky@chromium.org" Date: Fri, 8 Jan 2010 23:57:41 +0000 Subject: Changes synchronous session restore to create windows after nested message loop returns. The problem with the old approach was we created a bunch of windows than exited the nested message loop. But because exit isn't processed immediately it meant someone could also ask for the nested loop to be exited and then you're hosed (one nested message loop still running). BUG=22878 TEST=none Review URL: http://codereview.chromium.org/519090 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35850 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/sessions/session_restore.cc | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'chrome/browser/sessions') diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc index 36bc224..b549b04 100644 --- a/chrome/browser/sessions/session_restore.cc +++ b/chrome/browser/sessions/session_restore.cc @@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/scoped_ptr.h" +#include "base/stl_util-inl.h" #include "base/string_util.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" @@ -191,6 +192,7 @@ class SessionRestoreImpl : public NotificationObserver { if (synchronous_) { MessageLoop::current()->Run(); + ProcessSessionWindows(&windows_); delete this; return; } @@ -202,6 +204,7 @@ class SessionRestoreImpl : public NotificationObserver { } ~SessionRestoreImpl() { + STLDeleteElements(&windows_); } virtual void Observe(NotificationType type, @@ -238,9 +241,6 @@ class SessionRestoreImpl : public NotificationObserver { browser->window()->Show(); } - if (synchronous_) - MessageLoop::current()->Quit(); - if (succeeded) { DCHECK(tab_loader_.get()); // TabLoader delets itself when done loading. @@ -258,6 +258,16 @@ class SessionRestoreImpl : public NotificationObserver { void OnGotSession(SessionService::Handle handle, std::vector* windows) { + if (synchronous_) { + // See comment above windows_ as to why we don't process immediately. + windows_.swap(*windows); + MessageLoop::current()->Quit(); + return; + } + ProcessSessionWindows(windows); + } + + void ProcessSessionWindows(std::vector* windows) { if (windows->empty()) { // Restore was unsuccessful. FinishedTabCreation(false, false); @@ -417,6 +427,12 @@ class SessionRestoreImpl : public NotificationObserver { // Responsible for loading the tabs. scoped_ptr tab_loader_; + // When synchronous we run a nested message loop. To avoid creating windows + // from the nested message loop (which can make exiting the nested message + // loop take a while) we cache the SessionWindows here and create the actual + // windows when the nested message loop exits. + std::vector windows_; + NotificationRegistrar registrar_; }; -- cgit v1.1