Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(487)

Side by Side Diff: chrome/browser/prerender/prerender_contents.cc

Issue 7017014: Fix issues when PrerenderContents::Destroy() is called during TabContents destruction. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Sync Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/prerender/prerender_contents.h" 5 #include "chrome/browser/prerender/prerender_contents.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/process_util.h" 10 #include "base/process_util.h"
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 : prerender_manager_(prerender_manager), 130 : prerender_manager_(prerender_manager),
131 render_view_host_(NULL), 131 render_view_host_(NULL),
132 prerender_url_(url), 132 prerender_url_(url),
133 referrer_(referrer), 133 referrer_(referrer),
134 profile_(profile), 134 profile_(profile),
135 page_id_(0), 135 page_id_(0),
136 ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_observer_registrar_(this)), 136 ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_observer_registrar_(this)),
137 has_stopped_loading_(false), 137 has_stopped_loading_(false),
138 final_status_(FINAL_STATUS_MAX), 138 final_status_(FINAL_STATUS_MAX),
139 prerendering_has_started_(false), 139 prerendering_has_started_(false),
140 prerendering_has_been_cancelled_(false),
140 child_id_(-1), 141 child_id_(-1),
141 route_id_(-1) { 142 route_id_(-1) {
142 DCHECK(prerender_manager != NULL); 143 DCHECK(prerender_manager != NULL);
143 } 144 }
144 145
145 bool PrerenderContents::Init() { 146 bool PrerenderContents::Init() {
146 if (!AddAliasURL(prerender_url_)) 147 if (!AddAliasURL(prerender_url_))
147 return false; 148 return false;
148 return true; 149 return true;
149 } 150 }
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 358
358 final_status_ = final_status; 359 final_status_ = final_status;
359 } 360 }
360 361
361 FinalStatus PrerenderContents::final_status() const { 362 FinalStatus PrerenderContents::final_status() const {
362 return final_status_; 363 return final_status_;
363 } 364 }
364 365
365 PrerenderContents::~PrerenderContents() { 366 PrerenderContents::~PrerenderContents() {
366 DCHECK(final_status_ != FINAL_STATUS_MAX); 367 DCHECK(final_status_ != FINAL_STATUS_MAX);
368 DCHECK(prerendering_has_been_cancelled_ ||
369 final_status_ == FINAL_STATUS_USED ||
370 final_status_ == FINAL_STATUS_CONTROL_GROUP);
367 371
368 // If we haven't even started prerendering, we were just in the control 372 // If we haven't even started prerendering, we were just in the control
369 // group, which means we do not want to record the status. 373 // group, which means we do not want to record the status.
370 if (prerendering_has_started()) 374 if (prerendering_has_started())
371 RecordFinalStatus(final_status_); 375 RecordFinalStatus(final_status_);
372 376
373 // Only delete the RenderViewHost if we own it. 377 // Only delete the RenderViewHost if we own it.
374 if (render_view_host_) 378 if (render_view_host_)
375 render_view_host_->Shutdown(); 379 render_view_host_->Shutdown();
376 380
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 707
704 void PrerenderContents::OnRenderViewGone(int status, int exit_code) { 708 void PrerenderContents::OnRenderViewGone(int status, int exit_code) {
705 Destroy(FINAL_STATUS_RENDERER_CRASHED); 709 Destroy(FINAL_STATUS_RENDERER_CRASHED);
706 } 710 }
707 711
708 void PrerenderContents::DidStopLoading() { 712 void PrerenderContents::DidStopLoading() {
709 has_stopped_loading_ = true; 713 has_stopped_loading_ = true;
710 } 714 }
711 715
712 void PrerenderContents::Destroy(FinalStatus final_status) { 716 void PrerenderContents::Destroy(FinalStatus final_status) {
713 if (prerender_manager_->IsPendingDelete(this)) 717 if (prerendering_has_been_cancelled_)
714 return; 718 return;
715 719
720 prerendering_has_been_cancelled_ = true;
721 prerender_manager_->MoveEntryToPendingDelete(this);
cbentzel 2011/05/23 18:51:28 Is there a reason MoveEntryToPendingDelete moved u
mmenke 2011/05/23 18:55:36 Yes, it's just for style - prerender_has_been_canc
722
716 if (child_id_ != -1 && route_id_ != -1) { 723 if (child_id_ != -1 && route_id_ != -1) {
717 // Cancel the prerender in the PrerenderTracker. This is needed 724 // Cancel the prerender in the PrerenderTracker. This is needed
718 // because destroy may be called directly from the UI thread without calling 725 // because destroy may be called directly from the UI thread without calling
719 // TryCancel(). This is difficult to completely avoid, since prerendering 726 // TryCancel(). This is difficult to completely avoid, since prerendering
720 // can be cancelled before a RenderView is created. 727 // can be cancelled before a RenderView is created.
721 bool is_cancelled = 728 bool is_cancelled =
722 PrerenderTracker::GetInstance()->TryCancel(child_id_, route_id_, 729 PrerenderTracker::GetInstance()->TryCancel(child_id_, route_id_,
723 final_status); 730 final_status);
724 CHECK(is_cancelled); 731 CHECK(is_cancelled);
725 732
726 // A different final status may have been set already from another thread. 733 // A different final status may have been set already from another thread.
727 // If so, use it instead. 734 // If so, use it instead.
728 if (!PrerenderTracker::GetInstance()->GetFinalStatus(child_id_, route_id_, 735 if (!PrerenderTracker::GetInstance()->GetFinalStatus(child_id_, route_id_,
729 &final_status)) { 736 &final_status)) {
730 NOTREACHED(); 737 NOTREACHED();
731 } 738 }
732 } 739 }
740 set_final_status(final_status);
733 741
734 prerender_manager_->MoveEntryToPendingDelete(this);
735 set_final_status(final_status);
736 // We may destroy the PrerenderContents before we have initialized the 742 // We may destroy the PrerenderContents before we have initialized the
737 // RenderViewHost. Otherwise set the Observer's PrerenderContents to NULL to 743 // RenderViewHost. Otherwise set the Observer's PrerenderContents to NULL to
738 // avoid any more messages being sent. 744 // avoid any more messages being sent.
739 if (render_view_host_observer_.get()) 745 if (render_view_host_observer_.get())
740 render_view_host_observer_->set_prerender_contents(NULL); 746 render_view_host_observer_->set_prerender_contents(NULL);
741 } 747 }
742 748
743 void PrerenderContents::RendererUnresponsive(RenderViewHost* render_view_host, 749 void PrerenderContents::RendererUnresponsive(RenderViewHost* render_view_host,
744 bool is_during_unload) { 750 bool is_during_unload) {
745 DCHECK_EQ(render_view_host_, render_view_host); 751 DCHECK_EQ(render_view_host_, render_view_host);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 } 828 }
823 return render_view_host_; 829 return render_view_host_;
824 } 830 }
825 831
826 void PrerenderContents::CommitHistory(TabContents* tc) { 832 void PrerenderContents::CommitHistory(TabContents* tc) {
827 if (tab_contents_delegate_.get()) 833 if (tab_contents_delegate_.get())
828 tab_contents_delegate_->CommitHistory(tc); 834 tab_contents_delegate_->CommitHistory(tc);
829 } 835 }
830 836
831 } // namespace prerender 837 } // namespace prerender
OLDNEW
« no previous file with comments | « chrome/browser/prerender/prerender_contents.h ('k') | chrome/browser/prerender/prerender_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698