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

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

Issue 7038012: Safely cancel prerenders on threads other than the UI thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix linux 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_manager.h" 5 #include "chrome/browser/prerender/prerender_manager.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/field_trial.h" 10 #include "base/metrics/field_trial.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/time.h" 12 #include "base/time.h"
13 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
14 #include "chrome/browser/favicon/favicon_tab_helper.h" 14 #include "chrome/browser/favicon/favicon_tab_helper.h"
15 #include "chrome/browser/prerender/prerender_contents.h" 15 #include "chrome/browser/prerender/prerender_contents.h"
16 #include "chrome/browser/prerender/prerender_final_status.h" 16 #include "chrome/browser/prerender/prerender_final_status.h"
17 #include "chrome/browser/prerender/prerender_tracker.h"
17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h" 20 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h"
20 #include "chrome/common/render_messages.h" 21 #include "chrome/common/render_messages.h"
21 #include "content/browser/browser_thread.h" 22 #include "content/browser/browser_thread.h"
22 #include "content/browser/renderer_host/render_view_host.h" 23 #include "content/browser/renderer_host/render_view_host.h"
23 #include "content/browser/renderer_host/render_process_host.h" 24 #include "content/browser/renderer_host/render_process_host.h"
24 #include "content/browser/renderer_host/resource_dispatcher_host.h" 25 #include "content/browser/renderer_host/resource_dispatcher_host.h"
25 #include "content/browser/tab_contents/render_view_host_manager.h" 26 #include "content/browser/tab_contents/render_view_host_manager.h"
26 #include "content/browser/tab_contents/tab_contents.h" 27 #include "content/browser/tab_contents/tab_contents.h"
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 prerender_contents->Destroy(final_status); 372 prerender_contents->Destroy(final_status);
372 } 373 }
373 } 374 }
374 375
375 void PrerenderManager::DeleteOldEntries() { 376 void PrerenderManager::DeleteOldEntries() {
376 DCHECK(CalledOnValidThread()); 377 DCHECK(CalledOnValidThread());
377 while (!prerender_list_.empty()) { 378 while (!prerender_list_.empty()) {
378 PrerenderContentsData data = prerender_list_.front(); 379 PrerenderContentsData data = prerender_list_.front();
379 if (IsPrerenderElementFresh(data.start_time_)) 380 if (IsPrerenderElementFresh(data.start_time_))
380 return; 381 return;
381 prerender_list_.pop_front(); 382 data.contents_->Destroy(FINAL_STATUS_TIMED_OUT);
382 data.contents_->set_final_status(FINAL_STATUS_TIMED_OUT);
383 delete data.contents_;
384 } 383 }
385 MaybeStopSchedulingPeriodicCleanups(); 384 MaybeStopSchedulingPeriodicCleanups();
386 } 385 }
387 386
388 PrerenderContents* PrerenderManager::GetEntryButNotSpecifiedTC( 387 PrerenderContents* PrerenderManager::GetEntryButNotSpecifiedTC(
389 const GURL& url, 388 const GURL& url,
390 TabContents *tc) { 389 TabContents *tc) {
391 DCHECK(CalledOnValidThread()); 390 DCHECK(CalledOnValidThread());
392 DeleteOldEntries(); 391 DeleteOldEntries();
393 DeletePendingDeleteEntries(); 392 DeletePendingDeleteEntries();
(...skipping 26 matching lines...) Expand all
420 return false; 419 return false;
421 420
422 // If we are just in the control group (which can be detected by noticing 421 // If we are just in the control group (which can be detected by noticing
423 // that prerendering hasn't even started yet), record that |tab_contents| now 422 // that prerendering hasn't even started yet), record that |tab_contents| now
424 // would be showing a prerendered contents, but otherwise, don't do anything. 423 // would be showing a prerendered contents, but otherwise, don't do anything.
425 if (!prerender_contents->prerendering_has_started()) { 424 if (!prerender_contents->prerendering_has_started()) {
426 MarkTabContentsAsWouldBePrerendered(tab_contents); 425 MarkTabContentsAsWouldBePrerendered(tab_contents);
427 return false; 426 return false;
428 } 427 }
429 428
429 int child_id, route_id;
430 CHECK(prerender_contents->GetChildId(&child_id));
431 CHECK(prerender_contents->GetRouteId(&route_id));
432
433 // Try to set the prerendered page as used, so any subsequent attempts to
434 // cancel on other threads will fail. If this fails because the prerender
435 // was already cancelled, possibly on another thread, fail.
436 if (!PrerenderTracker::GetInstance()->TryUse(child_id, route_id))
437 return false;
438
430 if (!prerender_contents->load_start_time().is_null()) 439 if (!prerender_contents->load_start_time().is_null())
431 RecordTimeUntilUsed(GetCurrentTimeTicks() - 440 RecordTimeUntilUsed(GetCurrentTimeTicks() -
432 prerender_contents->load_start_time()); 441 prerender_contents->load_start_time());
433 442
434 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount", 443 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount",
435 ++prerenders_per_session_count_); 444 ++prerenders_per_session_count_);
436 prerender_contents->set_final_status(FINAL_STATUS_USED); 445 prerender_contents->set_final_status(FINAL_STATUS_USED);
437 446
438 int child_id;
439 int route_id;
440 CHECK(prerender_contents->GetChildId(&child_id));
441 CHECK(prerender_contents->GetRouteId(&route_id));
442
443 RenderViewHost* render_view_host = 447 RenderViewHost* render_view_host =
444 prerender_contents->render_view_host_mutable(); 448 prerender_contents->render_view_host_mutable();
445 prerender_contents->set_render_view_host(NULL); 449 prerender_contents->set_render_view_host(NULL);
446 450
447 // RenderViewHosts in PrerenderContents start out hidden. 451 // RenderViewHosts in PrerenderContents start out hidden.
448 // Since we are actually using it now, restore it. 452 // Since we are actually using it now, restore it.
449 render_view_host->WasRestored(); 453 render_view_host->WasRestored();
450 render_view_host->Send( 454 render_view_host->Send(
451 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false)); 455 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false));
452 tab_contents->SwapInRenderViewHost(render_view_host); 456 tab_contents->SwapInRenderViewHost(render_view_host);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 return false; 516 return false;
513 517
514 // If we are just in the control group (which can be detected by noticing 518 // If we are just in the control group (which can be detected by noticing
515 // that prerendering hasn't even started yet), record that |tab_contents| now 519 // that prerendering hasn't even started yet), record that |tab_contents| now
516 // would be showing a prerendered contents, but otherwise, don't do anything. 520 // would be showing a prerendered contents, but otherwise, don't do anything.
517 if (!prerender_contents->prerendering_has_started()) { 521 if (!prerender_contents->prerendering_has_started()) {
518 MarkTabContentsAsWouldBePrerendered(tab_contents); 522 MarkTabContentsAsWouldBePrerendered(tab_contents);
519 return false; 523 return false;
520 } 524 }
521 525
526 int child_id, route_id;
527 CHECK(prerender_contents->GetChildId(&child_id));
528 CHECK(prerender_contents->GetRouteId(&route_id));
529
530 // Try to set the prerendered page as used, so any subsequent attempts to
531 // cancel on other threads will fail. If this fails because the prerender
532 // was already cancelled, possibly on another thread, fail.
533 if (!PrerenderTracker::GetInstance()->TryUse(child_id, route_id))
534 return false;
535
522 if (!prerender_contents->load_start_time().is_null()) 536 if (!prerender_contents->load_start_time().is_null())
523 RecordTimeUntilUsed(GetCurrentTimeTicks() - 537 RecordTimeUntilUsed(GetCurrentTimeTicks() -
524 prerender_contents->load_start_time()); 538 prerender_contents->load_start_time());
525 539
526 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount", 540 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount",
527 ++prerenders_per_session_count_); 541 ++prerenders_per_session_count_);
528 prerender_contents->set_final_status(FINAL_STATUS_USED); 542 prerender_contents->set_final_status(FINAL_STATUS_USED);
529 543
530 int child_id;
531 int route_id;
532 CHECK(prerender_contents->GetChildId(&child_id));
533 CHECK(prerender_contents->GetRouteId(&route_id));
534
535 RenderViewHost* render_view_host = 544 RenderViewHost* render_view_host =
536 prerender_contents->prerender_contents()->render_view_host(); 545 prerender_contents->prerender_contents()->render_view_host();
537 DCHECK(render_view_host); 546 DCHECK(render_view_host);
538 render_view_host->Send( 547 render_view_host->Send(
539 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false)); 548 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false));
540 549
541 TabContentsWrapper* new_tab_contents = 550 TabContentsWrapper* new_tab_contents =
542 prerender_contents->ReleasePrerenderContents(); 551 prerender_contents->ReleasePrerenderContents();
543 TabContentsWrapper* old_tab_contents = 552 TabContentsWrapper* old_tab_contents =
544 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents); 553 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 return prerendered_tab_contents_set_.count(tab_contents) > 0; 921 return prerendered_tab_contents_set_.count(tab_contents) > 0;
913 } 922 }
914 923
915 bool PrerenderManager::WouldTabContentsBePrerendered( 924 bool PrerenderManager::WouldTabContentsBePrerendered(
916 TabContents* tab_contents) const { 925 TabContents* tab_contents) const {
917 DCHECK(CalledOnValidThread()); 926 DCHECK(CalledOnValidThread());
918 return would_be_prerendered_tab_contents_set_.count(tab_contents) > 0; 927 return would_be_prerendered_tab_contents_set_.count(tab_contents) > 0;
919 } 928 }
920 929
921 } // namespace prerender 930 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698