summaryrefslogtreecommitdiffstats
path: root/chrome/browser/prerender
diff options
context:
space:
mode:
authormmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-04 15:20:09 +0000
committermmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-04 15:20:09 +0000
commitc98fd5d88d2a45bf0f59c4695171285334b91029 (patch)
tree28c01c0aff59b640847f319c6cde4ac1f7089e40 /chrome/browser/prerender
parent24abaefe28cbdf9a6dd21d84f1ad5f92ec11357c (diff)
downloadchromium_src-c98fd5d88d2a45bf0f59c4695171285334b91029.zip
chromium_src-c98fd5d88d2a45bf0f59c4695171285334b91029.tar.gz
chromium_src-c98fd5d88d2a45bf0f59c4695171285334b91029.tar.bz2
Don't destroy a TabContents while prerendering until
after the rest of its observers have been looped through. Bug=81452 Test=Enable new prerendering code, apply http://codereview.chromium.org/6911004/, launch in debug mode, go to a page with a prerender link, visit the prerendered page. Note lack of a warning. Review URL: http://codereview.chromium.org/6912036 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84062 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/prerender')
-rw-r--r--chrome/browser/prerender/prerender_manager.cc38
-rw-r--r--chrome/browser/prerender/prerender_manager.h12
2 files changed, 39 insertions, 11 deletions
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index c545f11..67ca43f 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -208,6 +208,7 @@ PrerenderManager::PrerenderManager(Profile* profile)
}
PrerenderManager::~PrerenderManager() {
+ DeleteOldTabContents();
while (!prerender_list_.empty()) {
PrerenderContentsData data = prerender_list_.front();
prerender_list_.pop_front();
@@ -382,8 +383,7 @@ void PrerenderManager::DeleteOldEntries() {
data.contents_->set_final_status(FINAL_STATUS_TIMED_OUT);
delete data.contents_;
}
- if (prerender_list_.empty())
- StopSchedulingPeriodicCleanups();
+ MaybeStopSchedulingPeriodicCleanups();
}
PrerenderContents* PrerenderManager::GetEntryButNotSpecifiedTC(
@@ -544,16 +544,20 @@ bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tab_contents,
render_view_host->Send(
new ViewMsg_DisplayPrerenderedPage(render_view_host->routing_id()));
*/
- TabContentsWrapper* new_tc = prerender_contents->ReleasePrerenderContents();
- TabContentsWrapper* old_tc =
+ TabContentsWrapper* new_tab_contents =
+ prerender_contents->ReleasePrerenderContents();
+ TabContentsWrapper* old_tab_contents =
TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
- DCHECK(new_tc);
- DCHECK(old_tc);
+ DCHECK(new_tab_contents);
+ DCHECK(old_tab_contents);
// Merge the browsing history.
- new_tc->controller().CopyStateFromAndPrune(&old_tc->controller(), false);
+ new_tab_contents->controller().CopyStateFromAndPrune(
+ &old_tab_contents->controller(),
+ false);
- old_tc->delegate()->SwapTabContents(old_tc, new_tc);
+ old_tab_contents->delegate()->SwapTabContents(old_tab_contents,
+ new_tab_contents);
MarkTabContentsAsPrerendered(tab_contents);
@@ -576,6 +580,8 @@ bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tab_contents,
Source<std::pair<int, int> >(&child_route_pair),
NotificationService::NoDetails());
+ old_tab_contents_list_.push_back(old_tab_contents);
+ StartSchedulingPeriodicCleanups();
return true;
}
@@ -789,14 +795,28 @@ void PrerenderManager::StartSchedulingPeriodicCleanups() {
&PrerenderManager::PeriodicCleanup);
}
-void PrerenderManager::StopSchedulingPeriodicCleanups() {
+void PrerenderManager::MaybeStopSchedulingPeriodicCleanups() {
+ if (!old_tab_contents_list_.empty() || !prerender_list_.empty())
+ return;
+
DCHECK(CalledOnValidThread());
repeating_timer_.Stop();
}
+void PrerenderManager::DeleteOldTabContents() {
+ while (!old_tab_contents_list_.empty()) {
+ TabContentsWrapper* tab_contents = old_tab_contents_list_.front();
+ old_tab_contents_list_.pop_front();
+ delete tab_contents;
+ }
+ MaybeStopSchedulingPeriodicCleanups();
+}
+
void PrerenderManager::PeriodicCleanup() {
DCHECK(CalledOnValidThread());
+ DeleteOldTabContents();
DeleteOldEntries();
+
// Grab a copy of the current PrerenderContents pointers, so that we
// will not interfere with potential deletions of the list.
std::vector<PrerenderContents*> prerender_contents;
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index f1f46ff..5577ceb 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -191,9 +191,10 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
struct PrerenderContentsData;
- // Starts and stops scheduling periodic cleanups, respectively.
+ // Starts scheduling periodic cleanups.
void StartSchedulingPeriodicCleanups();
- void StopSchedulingPeriodicCleanups();
+ // Stops scheduling periodic cleanups if they're no longer needed.
+ void MaybeStopSchedulingPeriodicCleanups();
// Deletes stale prerendered PrerenderContents.
// Also identifies and kills PrerenderContents that use too much
@@ -230,6 +231,11 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
bool DoesRateLimitAllowPrerender() const;
+ // Deletes old TabContents that have been replaced by prerendered ones. This
+ // is needed because they're replaced in a callback from the old TabContents,
+ // so cannot immediately be deleted.
+ void DeleteOldTabContents();
+
// Specifies whether prerendering is currently enabled for this
// manager. The value can change dynamically during the lifetime
// of the PrerenderManager.
@@ -278,6 +284,8 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
// Track time of last prerender to limit prerender spam.
base::TimeTicks last_prerender_start_time_;
+ std::list<TabContentsWrapper*> old_tab_contents_list_;
+
DISALLOW_COPY_AND_ASSIGN(PrerenderManager);
};