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

Side by Side Diff: content/browser/loader/resource_dispatcher_host_impl.cc

Issue 11270027: Add a ResourceScheduler to ResourceDispatcherHost. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove all linked_ptrs Created 8 years 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading
6 6
7 #include "content/browser/loader/resource_dispatcher_host_impl.h" 7 #include "content/browser/loader/resource_dispatcher_host_impl.h"
8 8
9 #include <set> 9 #include <set>
10 #include <vector> 10 #include <vector>
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 BrowserThread::IO, FROM_HERE, 372 BrowserThread::IO, FROM_HERE,
373 base::Bind(&appcache::AppCacheInterceptor::EnsureRegistered)); 373 base::Bind(&appcache::AppCacheInterceptor::EnsureRegistered));
374 374
375 update_load_states_timer_.reset( 375 update_load_states_timer_.reset(
376 new base::RepeatingTimer<ResourceDispatcherHostImpl>()); 376 new base::RepeatingTimer<ResourceDispatcherHostImpl>());
377 } 377 }
378 378
379 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { 379 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() {
380 DCHECK(g_resource_dispatcher_host); 380 DCHECK(g_resource_dispatcher_host);
381 g_resource_dispatcher_host = NULL; 381 g_resource_dispatcher_host = NULL;
382 STLDeleteContainerPairSecondPointers(pending_loaders_.begin(),
383 pending_loaders_.end());
382 } 384 }
383 385
384 // static 386 // static
385 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() { 387 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() {
386 return g_resource_dispatcher_host; 388 return g_resource_dispatcher_host;
387 } 389 }
388 390
389 void ResourceDispatcherHostImpl::SetDelegate( 391 void ResourceDispatcherHostImpl::SetDelegate(
390 ResourceDispatcherHostDelegate* delegate) { 392 ResourceDispatcherHostDelegate* delegate) {
391 delegate_ = delegate; 393 delegate_ = delegate;
(...skipping 17 matching lines...) Expand all
409 ResourceContext* context) { 411 ResourceContext* context) {
410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
411 DCHECK(context); 413 DCHECK(context);
412 414
413 CHECK(ContainsKey(active_resource_contexts_, context)); 415 CHECK(ContainsKey(active_resource_contexts_, context));
414 416
415 // Note that request cancellation has side effects. Therefore, we gather all 417 // Note that request cancellation has side effects. Therefore, we gather all
416 // the requests to cancel first, and then we start cancelling. We assert at 418 // the requests to cancel first, and then we start cancelling. We assert at
417 // the end that there are no more to cancel since the context is about to go 419 // the end that there are no more to cancel since the context is about to go
418 // away. 420 // away.
419 typedef std::vector<linked_ptr<ResourceLoader> > LoaderList; 421 typedef ScopedVector<ResourceLoader> LoaderList;
420 LoaderList loaders_to_cancel; 422 LoaderList loaders_to_cancel;
421 423
422 for (LoaderMap::iterator i = pending_loaders_.begin(); 424 for (LoaderMap::iterator i = pending_loaders_.begin();
423 i != pending_loaders_.end();) { 425 i != pending_loaders_.end();) {
424 if (i->second->GetRequestInfo()->GetContext() == context) { 426 if (i->second->GetRequestInfo()->GetContext() == context) {
425 loaders_to_cancel.push_back(i->second); 427 loaders_to_cancel.push_back(i->second);
426 pending_loaders_.erase(i++); 428 pending_loaders_.erase(i++);
427 } else { 429 } else {
428 ++i; 430 ++i;
429 } 431 }
430 } 432 }
431 433
432 for (BlockedLoadersMap::iterator i = blocked_loaders_map_.begin(); 434 for (BlockedLoadersMap::iterator i = blocked_loaders_map_.begin();
433 i != blocked_loaders_map_.end();) { 435 i != blocked_loaders_map_.end();) {
434 BlockedLoadersList* loaders = i->second; 436 BlockedLoadersList* loaders = i->second;
435 if (loaders->empty()) { 437 if (loaders->empty()) {
436 // This can happen if BlockRequestsForRoute() has been called for a route, 438 // This can happen if BlockRequestsForRoute() has been called for a route,
437 // but we haven't blocked any matching requests yet. 439 // but we haven't blocked any matching requests yet.
438 ++i; 440 ++i;
439 continue; 441 continue;
440 } 442 }
441 ResourceRequestInfoImpl* info = loaders->front()->GetRequestInfo(); 443 ResourceRequestInfoImpl* info = loaders->front()->GetRequestInfo();
442 if (info->GetContext() == context) { 444 if (info->GetContext() == context) {
443 blocked_loaders_map_.erase(i++); 445 blocked_loaders_map_.erase(i++);
444 for (BlockedLoadersList::const_iterator it = loaders->begin(); 446 for (BlockedLoadersList::const_iterator it = loaders->begin();
445 it != loaders->end(); ++it) { 447 it != loaders->end(); ++it) {
446 linked_ptr<ResourceLoader> loader = *it; 448 scoped_ptr<ResourceLoader> loader(*it);
447 info = loader->GetRequestInfo(); 449 info = loader->GetRequestInfo();
448 // We make the assumption that all requests on the list have the same 450 // We make the assumption that all requests on the list have the same
449 // ResourceContext. 451 // ResourceContext.
450 DCHECK_EQ(context, info->GetContext()); 452 DCHECK_EQ(context, info->GetContext());
451 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 453 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
452 info->GetChildID()); 454 info->GetChildID());
453 loaders_to_cancel.push_back(loader); 455 loaders_to_cancel.push_back(loader.release());
454 } 456 }
457 loaders->weak_clear();
455 delete loaders; 458 delete loaders;
456 } else { 459 } else {
457 ++i; 460 ++i;
458 } 461 }
459 } 462 }
460 463
461 #ifndef NDEBUG 464 #ifndef NDEBUG
462 for (LoaderList::iterator i = loaders_to_cancel.begin(); 465 for (LoaderList::iterator i = loaders_to_cancel.begin();
463 i != loaders_to_cancel.end(); ++i) { 466 i != loaders_to_cancel.end(); ++i) {
464 // There is no strict requirement that this be the case, but currently 467 // There is no strict requirement that this be the case, but currently
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 return false; 774 return false;
772 } 775 }
773 776
774 return info->GetAssociatedRenderView(render_process_id, render_view_id); 777 return info->GetAssociatedRenderView(render_process_id, render_view_id);
775 } 778 }
776 779
777 void ResourceDispatcherHostImpl::OnShutdown() { 780 void ResourceDispatcherHostImpl::OnShutdown() {
778 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 781 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
779 782
780 is_shutdown_ = true; 783 is_shutdown_ = true;
784 STLDeleteContainerPairSecondPointers(pending_loaders_.begin(),
darin (slow to review) 2012/12/14 22:16:28 makes me wish we had a ScopedMap type to go along
785 pending_loaders_.end());
781 pending_loaders_.clear(); 786 pending_loaders_.clear();
782 787
783 // Make sure we shutdown the timer now, otherwise by the time our destructor 788 // Make sure we shutdown the timer now, otherwise by the time our destructor
784 // runs if the timer is still running the Task is deleted twice (once by 789 // runs if the timer is still running the Task is deleted twice (once by
785 // the MessageLoop and the second time by RepeatingTimer). 790 // the MessageLoop and the second time by RepeatingTimer).
786 update_load_states_timer_.reset(); 791 update_load_states_timer_.reset();
787 792
788 // Clear blocked requests if any left. 793 // Clear blocked requests if any left.
789 // Note that we have to do this in 2 passes as we cannot call 794 // Note that we have to do this in 2 passes as we cannot call
790 // CancelBlockedRequestsForRoute while iterating over 795 // CancelBlockedRequestsForRoute while iterating over
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 int child_id = filter_->child_id(); 872 int child_id = filter_->child_id();
868 873
869 // If we crash here, figure out what URL the renderer was requesting. 874 // If we crash here, figure out what URL the renderer was requesting.
870 // http://crbug.com/91398 875 // http://crbug.com/91398
871 char url_buf[128]; 876 char url_buf[128];
872 base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf)); 877 base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf));
873 base::debug::Alias(url_buf); 878 base::debug::Alias(url_buf);
874 879
875 // If the request that's coming in is being transferred from another process, 880 // If the request that's coming in is being transferred from another process,
876 // we want to reuse and resume the old loader rather than start a new one. 881 // we want to reuse and resume the old loader rather than start a new one.
877 linked_ptr<ResourceLoader> deferred_loader; 882 scoped_ptr<ResourceLoader> deferred_loader;
878 { 883 {
879 LoaderMap::iterator it = pending_loaders_.find( 884 LoaderMap::iterator it = pending_loaders_.find(
880 GlobalRequestID(request_data.transferred_request_child_id, 885 GlobalRequestID(request_data.transferred_request_child_id,
881 request_data.transferred_request_request_id)); 886 request_data.transferred_request_request_id));
882 if (it != pending_loaders_.end()) { 887 if (it != pending_loaders_.end()) {
883 if (it->second->is_transferring()) { 888 if (it->second->is_transferring()) {
884 deferred_loader = it->second; 889 deferred_loader.reset(it->second);
885 pending_loaders_.erase(it); 890 pending_loaders_.erase(it);
886 } else { 891 } else {
887 RecordAction(UserMetricsAction("BadMessageTerminate_RDH")); 892 RecordAction(UserMetricsAction("BadMessageTerminate_RDH"));
888 filter_->BadMessageReceived(); 893 filter_->BadMessageReceived();
889 return; 894 return;
890 } 895 }
891 } 896 }
892 } 897 }
893 898
894 ResourceContext* resource_context = filter_->resource_context(); 899 ResourceContext* resource_context = filter_->resource_context();
(...skipping 20 matching lines...) Expand all
915 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); 920 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id);
916 return; 921 return;
917 } 922 }
918 923
919 int load_flags = 924 int load_flags =
920 BuildLoadFlagsForRequest(request_data, child_id, sync_result != NULL); 925 BuildLoadFlagsForRequest(request_data, child_id, sync_result != NULL);
921 926
922 // Construct the request. 927 // Construct the request.
923 scoped_ptr<net::URLRequest> new_request; 928 scoped_ptr<net::URLRequest> new_request;
924 net::URLRequest* request; 929 net::URLRequest* request;
925 if (deferred_loader.get()) { 930 if (deferred_loader) {
926 request = deferred_loader->request(); 931 request = deferred_loader->request();
927 932
928 // Give the ResourceLoader (or any of the ResourceHandlers held by it) a 933 // Give the ResourceLoader (or any of the ResourceHandlers held by it) a
929 // chance to reset some state before we complete the transfer. 934 // chance to reset some state before we complete the transfer.
930 deferred_loader->WillCompleteTransfer(); 935 deferred_loader->WillCompleteTransfer();
931 } else { 936 } else {
932 net::URLRequestContext* context = 937 net::URLRequestContext* context =
933 filter_->GetURLRequestContext(request_data.resource_type); 938 filter_->GetURLRequestContext(request_data.resource_type);
934 new_request.reset(context->CreateRequest(request_data.url, NULL)); 939 new_request.reset(context->CreateRequest(request_data.url, NULL));
935 request = new_request.get(); 940 request = new_request.get();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 throttles.begin(), 1054 throttles.begin(),
1050 new TransferNavigationResourceThrottle(request)); 1055 new TransferNavigationResourceThrottle(request));
1051 } 1056 }
1052 1057
1053 if (!throttles.empty()) { 1058 if (!throttles.empty()) {
1054 handler.reset( 1059 handler.reset(
1055 new ThrottlingResourceHandler(handler.Pass(), child_id, request_id, 1060 new ThrottlingResourceHandler(handler.Pass(), child_id, request_id,
1056 throttles.Pass())); 1061 throttles.Pass()));
1057 } 1062 }
1058 1063
1059 if (deferred_loader.get()) { 1064 if (deferred_loader) {
1060 pending_loaders_[extra_info->GetGlobalRequestID()] = deferred_loader; 1065 pending_loaders_[extra_info->GetGlobalRequestID()] =
darin (slow to review) 2012/12/14 22:16:28 nit: seems a little bloaty codesighs-wise to repea
1061 deferred_loader->CompleteTransfer(handler.Pass()); 1066 deferred_loader.release();
1067 pending_loaders_[extra_info->GetGlobalRequestID()]->CompleteTransfer(
1068 handler.Pass());
1062 } else { 1069 } else {
1063 BeginRequestInternal(new_request.Pass(), handler.Pass()); 1070 BeginRequestInternal(new_request.Pass(), handler.Pass());
1064 } 1071 }
1065 } 1072 }
1066 1073
1067 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) { 1074 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) {
1068 UnregisterDownloadedTempFile(filter_->child_id(), request_id); 1075 UnregisterDownloadedTempFile(filter_->child_id(), request_id);
1069 } 1076 }
1070 1077
1071 void ResourceDispatcherHostImpl::OnDataReceivedACK(int request_id) { 1078 void ResourceDispatcherHostImpl::OnDataReceivedACK(int request_id) {
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 1380
1374 void ResourceDispatcherHostImpl::RemovePendingLoader( 1381 void ResourceDispatcherHostImpl::RemovePendingLoader(
1375 const LoaderMap::iterator& iter) { 1382 const LoaderMap::iterator& iter) {
1376 ResourceRequestInfoImpl* info = iter->second->GetRequestInfo(); 1383 ResourceRequestInfoImpl* info = iter->second->GetRequestInfo();
1377 1384
1378 // Remove the memory credit that we added when pushing the request onto 1385 // Remove the memory credit that we added when pushing the request onto
1379 // the pending list. 1386 // the pending list.
1380 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 1387 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
1381 info->GetChildID()); 1388 info->GetChildID());
1382 1389
1390 delete iter->second;
1383 pending_loaders_.erase(iter); 1391 pending_loaders_.erase(iter);
1384 1392
1385 // If we have no more pending requests, then stop the load state monitor 1393 // If we have no more pending requests, then stop the load state monitor
1386 if (pending_loaders_.empty() && update_load_states_timer_.get()) 1394 if (pending_loaders_.empty() && update_load_states_timer_.get())
1387 update_load_states_timer_->Stop(); 1395 update_load_states_timer_->Stop();
1388 } 1396 }
1389 1397
1390 void ResourceDispatcherHostImpl::CancelRequest(int child_id, 1398 void ResourceDispatcherHostImpl::CancelRequest(int child_id,
1391 int request_id, 1399 int request_id,
1392 bool from_renderer) { 1400 bool from_renderer) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 } 1486 }
1479 1487
1480 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 1488 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
1481 info->GetChildID()); 1489 info->GetChildID());
1482 1490
1483 // A ResourceHandler must not outlive its associated URLRequest. 1491 // A ResourceHandler must not outlive its associated URLRequest.
1484 handler.reset(); 1492 handler.reset();
1485 return; 1493 return;
1486 } 1494 }
1487 1495
1488 linked_ptr<ResourceLoader> loader( 1496 scoped_ptr<ResourceLoader> loader(
1489 new ResourceLoader(request.Pass(), handler.Pass(), this)); 1497 new ResourceLoader(request.Pass(), handler.Pass(), this));
1490 1498
1491 ProcessRouteIDs pair_id(info->GetChildID(), info->GetRouteID()); 1499 ProcessRouteIDs pair_id(info->GetChildID(), info->GetRouteID());
1492 BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(pair_id); 1500 BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(pair_id);
1493 if (iter != blocked_loaders_map_.end()) { 1501 if (iter != blocked_loaders_map_.end()) {
1494 // The request should be blocked. 1502 // The request should be blocked.
1495 iter->second->push_back(loader); 1503 iter->second->push_back(loader.release());
1496 return; 1504 return;
1497 } 1505 }
1498 1506
1499 StartLoading(info, loader); 1507 StartLoading(info, loader.Pass());
1500 } 1508 }
1501 1509
1502 void ResourceDispatcherHostImpl::StartLoading( 1510 void ResourceDispatcherHostImpl::StartLoading(
1503 ResourceRequestInfoImpl* info, 1511 ResourceRequestInfoImpl* info,
1504 const linked_ptr<ResourceLoader>& loader) { 1512 scoped_ptr<ResourceLoader> loader) {
1505 pending_loaders_[info->GetGlobalRequestID()] = loader; 1513 pending_loaders_[info->GetGlobalRequestID()] = loader.release();
darin (slow to review) 2012/12/14 22:16:28 same nit
1506 1514 pending_loaders_[info->GetGlobalRequestID()]->ScheduleRequest(
darin (slow to review) 2012/12/14 22:16:28 This feels a bit awkward to me. I don't think the
1507 loader->StartRequest(); 1515 &resource_scheduler_);
1508 } 1516 }
1509 1517
1510 void ResourceDispatcherHostImpl::OnUserGesture(WebContentsImpl* contents) { 1518 void ResourceDispatcherHostImpl::OnUserGesture(WebContentsImpl* contents) {
1511 last_user_gesture_time_ = TimeTicks::Now(); 1519 last_user_gesture_time_ = TimeTicks::Now();
1512 } 1520 }
1513 1521
1514 net::URLRequest* ResourceDispatcherHostImpl::GetURLRequest( 1522 net::URLRequest* ResourceDispatcherHostImpl::GetURLRequest(
1515 const GlobalRequestID& id) { 1523 const GlobalRequestID& id) {
1516 ResourceLoader* loader = GetLoader(id); 1524 ResourceLoader* loader = GetLoader(id);
1517 if (!loader) 1525 if (!loader)
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 return; 1671 return;
1664 } 1672 }
1665 1673
1666 BlockedLoadersList* loaders = iter->second; 1674 BlockedLoadersList* loaders = iter->second;
1667 1675
1668 // Removing the vector from the map unblocks any subsequent requests. 1676 // Removing the vector from the map unblocks any subsequent requests.
1669 blocked_loaders_map_.erase(iter); 1677 blocked_loaders_map_.erase(iter);
1670 1678
1671 for (BlockedLoadersList::iterator loaders_iter = loaders->begin(); 1679 for (BlockedLoadersList::iterator loaders_iter = loaders->begin();
1672 loaders_iter != loaders->end(); ++loaders_iter) { 1680 loaders_iter != loaders->end(); ++loaders_iter) {
1673 linked_ptr<ResourceLoader> loader = *loaders_iter; 1681 scoped_ptr<ResourceLoader> loader(*loaders_iter);
1674 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); 1682 ResourceRequestInfoImpl* info = loader->GetRequestInfo();
1675 if (cancel_requests) { 1683 if (cancel_requests) {
1676 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 1684 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
1677 info->GetChildID()); 1685 info->GetChildID());
1678 } else { 1686 } else {
1679 StartLoading(info, loader); 1687 StartLoading(info, loader.Pass());
1680 } 1688 }
1681 } 1689 }
1682 1690
1691 loaders->weak_clear();
1683 delete loaders; 1692 delete loaders;
1684 } 1693 }
1685 1694
1686 ResourceDispatcherHostImpl::HttpAuthResourceType 1695 ResourceDispatcherHostImpl::HttpAuthResourceType
1687 ResourceDispatcherHostImpl::HttpAuthResourceTypeOf(net::URLRequest* request) { 1696 ResourceDispatcherHostImpl::HttpAuthResourceTypeOf(net::URLRequest* request) {
1688 // Use the same critera as for cookies to determine the sub-resource type 1697 // Use the same critera as for cookies to determine the sub-resource type
1689 // that is requesting to be authenticated. 1698 // that is requesting to be authenticated.
1690 if (!request->first_party_for_cookies().is_valid()) 1699 if (!request->first_party_for_cookies().is_valid())
1691 return HTTP_AUTH_RESOURCE_TOP; 1700 return HTTP_AUTH_RESOURCE_TOP;
1692 1701
(...skipping 18 matching lines...) Expand all
1711 } 1720 }
1712 1721
1713 ResourceLoader* ResourceDispatcherHostImpl::GetLoader( 1722 ResourceLoader* ResourceDispatcherHostImpl::GetLoader(
1714 const GlobalRequestID& id) const { 1723 const GlobalRequestID& id) const {
1715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1724 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1716 1725
1717 LoaderMap::const_iterator i = pending_loaders_.find(id); 1726 LoaderMap::const_iterator i = pending_loaders_.find(id);
1718 if (i == pending_loaders_.end()) 1727 if (i == pending_loaders_.end())
1719 return NULL; 1728 return NULL;
1720 1729
1721 return i->second.get(); 1730 return i->second;
1722 } 1731 }
1723 1732
1724 ResourceLoader* ResourceDispatcherHostImpl::GetLoader(int child_id, 1733 ResourceLoader* ResourceDispatcherHostImpl::GetLoader(
1725 int request_id) const { 1734 int child_id, int request_id) const {
1726 return GetLoader(GlobalRequestID(child_id, request_id)); 1735 return GetLoader(GlobalRequestID(child_id, request_id));
1727 } 1736 }
1728 1737
1729 } // namespace content 1738 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698