summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-08 23:57:41 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-08 23:57:41 +0000
commit06479834b913a081780e145d94ab39f0d4b01941 (patch)
tree741b4623579cac89215c10bc0ec04f4708d7f7a0 /chrome/browser
parent70bbf1519e775b81fddea15bfdac88f811d4c228 (diff)
downloadchromium_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.cc22
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_;
};