diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-08 23:57:41 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-08 23:57:41 +0000 |
commit | 06479834b913a081780e145d94ab39f0d4b01941 (patch) | |
tree | 741b4623579cac89215c10bc0ec04f4708d7f7a0 /chrome/browser | |
parent | 70bbf1519e775b81fddea15bfdac88f811d4c228 (diff) | |
download | chromium_src-06479834b913a081780e145d94ab39f0d4b01941.zip chromium_src-06479834b913a081780e145d94ab39f0d4b01941.tar.gz chromium_src-06479834b913a081780e145d94ab39f0d4b01941.tar.bz2 |
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
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/sessions/session_restore.cc | 22 |
1 files changed, 19 insertions, 3 deletions
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<SessionWindow*>* 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<SessionWindow*>* 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<TabLoader> 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<SessionWindow*> windows_; + NotificationRegistrar registrar_; }; |