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

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: 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_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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 prerender_contents->Destroy(final_status); 384 prerender_contents->Destroy(final_status);
384 } 385 }
385 } 386 }
386 387
387 void PrerenderManager::DeleteOldEntries() { 388 void PrerenderManager::DeleteOldEntries() {
388 DCHECK(CalledOnValidThread()); 389 DCHECK(CalledOnValidThread());
389 while (!prerender_list_.empty()) { 390 while (!prerender_list_.empty()) {
390 PrerenderContentsData data = prerender_list_.front(); 391 PrerenderContentsData data = prerender_list_.front();
391 if (IsPrerenderElementFresh(data.start_time_)) 392 if (IsPrerenderElementFresh(data.start_time_))
392 return; 393 return;
393 prerender_list_.pop_front(); 394 data.contents_->Destroy(FINAL_STATUS_TIMED_OUT);
394 data.contents_->set_final_status(FINAL_STATUS_TIMED_OUT);
395 delete data.contents_;
396 } 395 }
397 MaybeStopSchedulingPeriodicCleanups(); 396 MaybeStopSchedulingPeriodicCleanups();
398 } 397 }
399 398
400 PrerenderContents* PrerenderManager::GetEntryButNotSpecifiedTC( 399 PrerenderContents* PrerenderManager::GetEntryButNotSpecifiedTC(
401 const GURL& url, 400 const GURL& url,
402 TabContents *tc) { 401 TabContents *tc) {
403 DCHECK(CalledOnValidThread()); 402 DCHECK(CalledOnValidThread());
404 DeleteOldEntries(); 403 DeleteOldEntries();
405 DeletePendingDeleteEntries(); 404 DeletePendingDeleteEntries();
(...skipping 26 matching lines...) Expand all
432 return false; 431 return false;
433 432
434 // If we are just in the control group (which can be detected by noticing 433 // If we are just in the control group (which can be detected by noticing
435 // that prerendering hasn't even started yet), record that |tab_contents| now 434 // that prerendering hasn't even started yet), record that |tab_contents| now
436 // would be showing a prerendered contents, but otherwise, don't do anything. 435 // would be showing a prerendered contents, but otherwise, don't do anything.
437 if (!prerender_contents->prerendering_has_started()) { 436 if (!prerender_contents->prerendering_has_started()) {
438 MarkTabContentsAsWouldBePrerendered(tab_contents); 437 MarkTabContentsAsWouldBePrerendered(tab_contents);
439 return false; 438 return false;
440 } 439 }
441 440
441 int child_id, route_id;
442 CHECK(prerender_contents->GetChildId(&child_id));
443 CHECK(prerender_contents->GetRouteId(&route_id));
444
445 // Try to set the prerendered page as used, so any subsequent attempts to
446 // cancel on other threads will fail. If this fails because the prerender
447 // was already cancelled, possibly on another thread, fail.
448 if (!PrerenderTracker::GetInstance()->TryUse(child_id, route_id))
449 return false;
450
442 if (!prerender_contents->load_start_time().is_null()) 451 if (!prerender_contents->load_start_time().is_null())
443 RecordTimeUntilUsed(GetCurrentTimeTicks() - 452 RecordTimeUntilUsed(GetCurrentTimeTicks() -
444 prerender_contents->load_start_time()); 453 prerender_contents->load_start_time());
445 454
446 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount", 455 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount",
447 ++prerenders_per_session_count_); 456 ++prerenders_per_session_count_);
448 prerender_contents->set_final_status(FINAL_STATUS_USED); 457 prerender_contents->set_final_status(FINAL_STATUS_USED);
449 458
450 int child_id;
451 int route_id;
452 CHECK(prerender_contents->GetChildId(&child_id));
453 CHECK(prerender_contents->GetRouteId(&route_id));
454
455 RenderViewHost* render_view_host = 459 RenderViewHost* render_view_host =
456 prerender_contents->render_view_host_mutable(); 460 prerender_contents->render_view_host_mutable();
457 prerender_contents->set_render_view_host(NULL); 461 prerender_contents->set_render_view_host(NULL);
458 462
459 // RenderViewHosts in PrerenderContents start out hidden. 463 // RenderViewHosts in PrerenderContents start out hidden.
460 // Since we are actually using it now, restore it. 464 // Since we are actually using it now, restore it.
461 render_view_host->WasRestored(); 465 render_view_host->WasRestored();
462 render_view_host->Send( 466 render_view_host->Send(
463 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false)); 467 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false));
464 tab_contents->SwapInRenderViewHost(render_view_host); 468 tab_contents->SwapInRenderViewHost(render_view_host);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 return false; 528 return false;
525 529
526 // If we are just in the control group (which can be detected by noticing 530 // If we are just in the control group (which can be detected by noticing
527 // that prerendering hasn't even started yet), record that |tab_contents| now 531 // that prerendering hasn't even started yet), record that |tab_contents| now
528 // would be showing a prerendered contents, but otherwise, don't do anything. 532 // would be showing a prerendered contents, but otherwise, don't do anything.
529 if (!prerender_contents->prerendering_has_started()) { 533 if (!prerender_contents->prerendering_has_started()) {
530 MarkTabContentsAsWouldBePrerendered(tab_contents); 534 MarkTabContentsAsWouldBePrerendered(tab_contents);
531 return false; 535 return false;
532 } 536 }
533 537
538 int child_id, route_id;
539 CHECK(prerender_contents->GetChildId(&child_id));
540 CHECK(prerender_contents->GetRouteId(&route_id));
541
542 // Try to set the prerendered page as used, so any subsequent attempts to
543 // cancel on other threads will fail. If this fails because the prerender
544 // was already cancelled, possibly on another thread, fail.
545 if (!PrerenderTracker::GetInstance()->TryUse(child_id, route_id))
546 return false;
547
534 if (!prerender_contents->load_start_time().is_null()) 548 if (!prerender_contents->load_start_time().is_null())
535 RecordTimeUntilUsed(GetCurrentTimeTicks() - 549 RecordTimeUntilUsed(GetCurrentTimeTicks() -
536 prerender_contents->load_start_time()); 550 prerender_contents->load_start_time());
537 551
538 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount", 552 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount",
539 ++prerenders_per_session_count_); 553 ++prerenders_per_session_count_);
540 prerender_contents->set_final_status(FINAL_STATUS_USED); 554 prerender_contents->set_final_status(FINAL_STATUS_USED);
541 555
542 int child_id;
543 int route_id;
544 CHECK(prerender_contents->GetChildId(&child_id));
545 CHECK(prerender_contents->GetRouteId(&route_id));
546
547 RenderViewHost* render_view_host = 556 RenderViewHost* render_view_host =
548 prerender_contents->prerender_contents()->render_view_host(); 557 prerender_contents->prerender_contents()->render_view_host();
549 DCHECK(render_view_host); 558 DCHECK(render_view_host);
550 render_view_host->Send( 559 render_view_host->Send(
551 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false)); 560 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false));
552 561
553 TabContentsWrapper* new_tab_contents = 562 TabContentsWrapper* new_tab_contents =
554 prerender_contents->ReleasePrerenderContents(); 563 prerender_contents->ReleasePrerenderContents();
555 TabContentsWrapper* old_tab_contents = 564 TabContentsWrapper* old_tab_contents =
556 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents); 565 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 base::TimeTicks cutoff = GetCurrentTimeTicks() - 977 base::TimeTicks cutoff = GetCurrentTimeTicks() -
969 base::TimeDelta::FromMilliseconds(kNavigationRecordWindowMs); 978 base::TimeDelta::FromMilliseconds(kNavigationRecordWindowMs);
970 while (!navigations_.empty()) { 979 while (!navigations_.empty()) {
971 if (navigations_.front().time_ > cutoff) 980 if (navigations_.front().time_ > cutoff)
972 break; 981 break;
973 navigations_.pop_front(); 982 navigations_.pop_front();
974 } 983 }
975 } 984 }
976 985
977 } // namespace prerender 986 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698