diff options
author | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-04 15:20:09 +0000 |
---|---|---|
committer | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-04 15:20:09 +0000 |
commit | c98fd5d88d2a45bf0f59c4695171285334b91029 (patch) | |
tree | 28c01c0aff59b640847f319c6cde4ac1f7089e40 /chrome/browser/prerender | |
parent | 24abaefe28cbdf9a6dd21d84f1ad5f92ec11357c (diff) | |
download | chromium_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.cc | 38 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_manager.h | 12 |
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); }; |