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

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

Issue 11270027: Add a ResourceScheduler to ResourceDispatcherHost. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Almost no 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/renderer_host/resource_dispatcher_host_impl.h" 7 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
8 8
9 #include <set> 9 #include <set>
10 #include <vector> 10 #include <vector>
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 ResourceContext* context) { 409 ResourceContext* context) {
410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
411 DCHECK(context); 411 DCHECK(context);
412 412
413 CHECK(ContainsKey(active_resource_contexts_, context)); 413 CHECK(ContainsKey(active_resource_contexts_, context));
414 414
415 // Note that request cancellation has side effects. Therefore, we gather all 415 // 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 416 // 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 417 // the end that there are no more to cancel since the context is about to go
418 // away. 418 // away.
419 typedef std::vector<linked_ptr<ResourceLoader> > LoaderList; 419 typedef ScopedVector<ResourceLoader> LoaderList;
420 LoaderList loaders_to_cancel; 420 LoaderList loaders_to_cancel;
421 421
422 for (LoaderMap::iterator i = pending_loaders_.begin(); 422 for (LoaderMap::iterator i = pending_loaders_.begin();
423 i != pending_loaders_.end();) { 423 i != pending_loaders_.end();) {
424 if (i->second->GetRequestInfo()->GetContext() == context) { 424 if (i->second->GetRequestInfo()->GetContext() == context) {
425 loaders_to_cancel.push_back(i->second); 425 loaders_to_cancel.push_back(i->second.release());
426 pending_loaders_.erase(i++); 426 pending_loaders_.erase(i++);
427 } else { 427 } else {
428 ++i; 428 ++i;
429 } 429 }
430 } 430 }
431 431
432 for (BlockedLoadersMap::iterator i = blocked_loaders_map_.begin(); 432 for (BlockedLoadersMap::iterator i = blocked_loaders_map_.begin();
433 i != blocked_loaders_map_.end();) { 433 i != blocked_loaders_map_.end();) {
434 BlockedLoadersList* loaders = i->second; 434 BlockedLoadersList* loaders = i->second;
435 if (loaders->empty()) { 435 if (loaders->empty()) {
436 // This can happen if BlockRequestsForRoute() has been called for a route, 436 // This can happen if BlockRequestsForRoute() has been called for a route,
437 // but we haven't blocked any matching requests yet. 437 // but we haven't blocked any matching requests yet.
438 ++i; 438 ++i;
439 continue; 439 continue;
440 } 440 }
441 ResourceRequestInfoImpl* info = loaders->front()->GetRequestInfo(); 441 ResourceRequestInfoImpl* info = loaders->front()->GetRequestInfo();
442 if (info->GetContext() == context) { 442 if (info->GetContext() == context) {
443 blocked_loaders_map_.erase(i++); 443 blocked_loaders_map_.erase(i++);
444 for (BlockedLoadersList::const_iterator it = loaders->begin(); 444 for (BlockedLoadersList::const_iterator it = loaders->begin();
445 it != loaders->end(); ++it) { 445 it != loaders->end(); ++it) {
446 linked_ptr<ResourceLoader> loader = *it; 446 scoped_ptr<ResourceLoader> loader(*it);
447 info = loader->GetRequestInfo(); 447 info = loader->GetRequestInfo();
448 // We make the assumption that all requests on the list have the same 448 // We make the assumption that all requests on the list have the same
449 // ResourceContext. 449 // ResourceContext.
450 DCHECK_EQ(context, info->GetContext()); 450 DCHECK_EQ(context, info->GetContext());
451 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 451 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
452 info->GetChildID()); 452 info->GetChildID());
453 loaders_to_cancel.push_back(loader); 453 loaders_to_cancel.push_back(loader.release());
454 } 454 }
455 loaders->weak_erase(loaders->begin(), loaders->end());
455 delete loaders; 456 delete loaders;
456 } else { 457 } else {
457 ++i; 458 ++i;
458 } 459 }
459 } 460 }
460 461
461 #ifndef NDEBUG 462 #ifndef NDEBUG
462 for (LoaderList::iterator i = loaders_to_cancel.begin(); 463 for (LoaderList::iterator i = loaders_to_cancel.begin();
463 i != loaders_to_cancel.end(); ++i) { 464 i != loaders_to_cancel.end(); ++i) {
464 // There is no strict requirement that this be the case, but currently 465 // There is no strict requirement that this be the case, but currently
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 ResourceLoader* loader, 650 ResourceLoader* loader,
650 net::SSLCertRequestInfo* cert_info) { 651 net::SSLCertRequestInfo* cert_info) {
651 if (delegate_ && !delegate_->AcceptSSLClientCertificateRequest( 652 if (delegate_ && !delegate_->AcceptSSLClientCertificateRequest(
652 loader->request(), cert_info)) { 653 loader->request(), cert_info)) {
653 return false; 654 return false;
654 } 655 }
655 656
656 return true; 657 return true;
657 } 658 }
658 659
659 bool ResourceDispatcherHostImpl::HandleExternalProtocol(ResourceLoader* loader, 660 bool ResourceDispatcherHostImpl::HandleExternalProtocol(
660 const GURL& url) { 661 ResourceLoader* loader,
662 const GURL& url) {
661 if (!delegate_) 663 if (!delegate_)
662 return false; 664 return false;
663 665
664 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); 666 ResourceRequestInfoImpl* info = loader->GetRequestInfo();
665 667
666 if (!ResourceType::IsFrame(info->GetResourceType())) 668 if (!ResourceType::IsFrame(info->GetResourceType()))
667 return false; 669 return false;
668 670
669 const net::URLRequestJobFactory* job_factory = 671 const net::URLRequestJobFactory* job_factory =
670 info->GetContext()->GetRequestContext()->job_factory(); 672 info->GetContext()->GetRequestContext()->job_factory();
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 int child_id = filter_->child_id(); 869 int child_id = filter_->child_id();
868 870
869 // If we crash here, figure out what URL the renderer was requesting. 871 // If we crash here, figure out what URL the renderer was requesting.
870 // http://crbug.com/91398 872 // http://crbug.com/91398
871 char url_buf[128]; 873 char url_buf[128];
872 base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf)); 874 base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf));
873 base::debug::Alias(url_buf); 875 base::debug::Alias(url_buf);
874 876
875 // If the request that's coming in is being transferred from another process, 877 // 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. 878 // we want to reuse and resume the old loader rather than start a new one.
877 linked_ptr<ResourceLoader> deferred_loader; 879 scoped_ptr<ResourceLoader> deferred_loader;
878 { 880 {
879 LoaderMap::iterator it = pending_loaders_.find( 881 LoaderMap::iterator it = pending_loaders_.find(
880 GlobalRequestID(request_data.transferred_request_child_id, 882 GlobalRequestID(request_data.transferred_request_child_id,
881 request_data.transferred_request_request_id)); 883 request_data.transferred_request_request_id));
882 if (it != pending_loaders_.end()) { 884 if (it != pending_loaders_.end()) {
883 if (it->second->is_transferring()) { 885 if (it->second->is_transferring()) {
884 deferred_loader = it->second; 886 deferred_loader.reset(it->second.release());
885 pending_loaders_.erase(it); 887 pending_loaders_.erase(it);
886 } else { 888 } else {
887 RecordAction(UserMetricsAction("BadMessageTerminate_RDH")); 889 RecordAction(UserMetricsAction("BadMessageTerminate_RDH"));
888 filter_->BadMessageReceived(); 890 filter_->BadMessageReceived();
889 return; 891 return;
890 } 892 }
891 } 893 }
892 } 894 }
893 895
894 ResourceContext* resource_context = filter_->resource_context(); 896 ResourceContext* resource_context = filter_->resource_context();
(...skipping 20 matching lines...) Expand all
915 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); 917 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id);
916 return; 918 return;
917 } 919 }
918 920
919 int load_flags = 921 int load_flags =
920 BuildLoadFlagsForRequest(request_data, child_id, sync_result != NULL); 922 BuildLoadFlagsForRequest(request_data, child_id, sync_result != NULL);
921 923
922 // Construct the request. 924 // Construct the request.
923 scoped_ptr<net::URLRequest> new_request; 925 scoped_ptr<net::URLRequest> new_request;
924 net::URLRequest* request; 926 net::URLRequest* request;
925 if (deferred_loader.get()) { 927 if (deferred_loader) {
926 request = deferred_loader->request(); 928 request = deferred_loader->request();
927 929
928 // Give the ResourceLoader (or any of the ResourceHandlers held by it) a 930 // Give the ResourceLoader (or any of the ResourceHandlers held by it) a
929 // chance to reset some state before we complete the transfer. 931 // chance to reset some state before we complete the transfer.
930 deferred_loader->WillCompleteTransfer(); 932 deferred_loader->WillCompleteTransfer();
931 } else { 933 } else {
932 net::URLRequestContext* context = 934 net::URLRequestContext* context =
933 filter_->GetURLRequestContext(request_data.resource_type); 935 filter_->GetURLRequestContext(request_data.resource_type);
934 new_request.reset(context->CreateRequest(request_data.url, NULL)); 936 new_request.reset(context->CreateRequest(request_data.url, NULL));
935 request = new_request.get(); 937 request = new_request.get();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 throttles.begin(), 1051 throttles.begin(),
1050 new TransferNavigationResourceThrottle(request)); 1052 new TransferNavigationResourceThrottle(request));
1051 } 1053 }
1052 1054
1053 if (!throttles.empty()) { 1055 if (!throttles.empty()) {
1054 handler.reset( 1056 handler.reset(
1055 new ThrottlingResourceHandler(handler.Pass(), child_id, request_id, 1057 new ThrottlingResourceHandler(handler.Pass(), child_id, request_id,
1056 throttles.Pass())); 1058 throttles.Pass()));
1057 } 1059 }
1058 1060
1059 if (deferred_loader.get()) { 1061 if (deferred_loader) {
1060 pending_loaders_[extra_info->GetGlobalRequestID()] = deferred_loader; 1062 pending_loaders_[extra_info->GetGlobalRequestID()] = make_linked_ptr(
1061 deferred_loader->CompleteTransfer(handler.Pass()); 1063 deferred_loader.release());
1064 pending_loaders_[extra_info->GetGlobalRequestID()]->CompleteTransfer(
1065 handler.Pass());
1062 } else { 1066 } else {
1063 BeginRequestInternal(new_request.Pass(), handler.Pass()); 1067 BeginRequestInternal(new_request.Pass(), handler.Pass());
1064 } 1068 }
1065 } 1069 }
1066 1070
1067 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) { 1071 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) {
1068 UnregisterDownloadedTempFile(filter_->child_id(), request_id); 1072 UnregisterDownloadedTempFile(filter_->child_id(), request_id);
1069 } 1073 }
1070 1074
1071 void ResourceDispatcherHostImpl::OnDataReceivedACK(int request_id) { 1075 void ResourceDispatcherHostImpl::OnDataReceivedACK(int request_id) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 const ViewMsg_SwapOut_Params& params) { 1185 const ViewMsg_SwapOut_Params& params) {
1182 // Call the real implementation with true, which means that we timed out. 1186 // Call the real implementation with true, which means that we timed out.
1183 HandleSwapOutACK(params, true); 1187 HandleSwapOutACK(params, true);
1184 } 1188 }
1185 1189
1186 void ResourceDispatcherHostImpl::HandleSwapOutACK( 1190 void ResourceDispatcherHostImpl::HandleSwapOutACK(
1187 const ViewMsg_SwapOut_Params& params, bool timed_out) { 1191 const ViewMsg_SwapOut_Params& params, bool timed_out) {
1188 // Closes for cross-site transitions are handled such that the cross-site 1192 // Closes for cross-site transitions are handled such that the cross-site
1189 // transition continues. 1193 // transition continues.
1190 ResourceLoader* loader = GetLoader(params.new_render_process_host_id, 1194 ResourceLoader* loader = GetLoader(params.new_render_process_host_id,
1191 params.new_request_id); 1195 params.new_request_id);
willchan no longer on Chromium 2012/12/05 04:37:00 indentation is off
James Simonsen 2012/12/14 20:23:23 Done.
1192 if (loader) { 1196 if (loader) {
1193 // The response we were meant to resume could have already been canceled. 1197 // The response we were meant to resume could have already been canceled.
1194 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); 1198 ResourceRequestInfoImpl* info = loader->GetRequestInfo();
1195 if (info->cross_site_handler()) 1199 if (info->cross_site_handler())
1196 info->cross_site_handler()->ResumeResponse(); 1200 info->cross_site_handler()->ResumeResponse();
1197 } 1201 }
1198 1202
1199 // Update the RenderViewHost's internal state after the ACK. 1203 // Update the RenderViewHost's internal state after the ACK.
1200 BrowserThread::PostTask( 1204 BrowserThread::PostTask(
1201 BrowserThread::UI, 1205 BrowserThread::UI,
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 } 1482 }
1479 1483
1480 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 1484 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
1481 info->GetChildID()); 1485 info->GetChildID());
1482 1486
1483 // A ResourceHandler must not outlive its associated URLRequest. 1487 // A ResourceHandler must not outlive its associated URLRequest.
1484 handler.reset(); 1488 handler.reset();
1485 return; 1489 return;
1486 } 1490 }
1487 1491
1488 linked_ptr<ResourceLoader> loader( 1492 scoped_ptr<ResourceLoader> loader(
1489 new ResourceLoader(request.Pass(), handler.Pass(), this)); 1493 new ResourceLoader(request.Pass(), handler.Pass(), this));
1490 1494
1491 ProcessRouteIDs pair_id(info->GetChildID(), info->GetRouteID()); 1495 ProcessRouteIDs pair_id(info->GetChildID(), info->GetRouteID());
1492 BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(pair_id); 1496 BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(pair_id);
1493 if (iter != blocked_loaders_map_.end()) { 1497 if (iter != blocked_loaders_map_.end()) {
1494 // The request should be blocked. 1498 // The request should be blocked.
1495 iter->second->push_back(loader); 1499 iter->second->push_back(loader.release());
1496 return; 1500 return;
1497 } 1501 }
1498 1502
1499 StartLoading(info, loader); 1503 StartLoading(info, loader.Pass());
1500 } 1504 }
1501 1505
1502 void ResourceDispatcherHostImpl::StartLoading( 1506 void ResourceDispatcherHostImpl::StartLoading(
1503 ResourceRequestInfoImpl* info, 1507 ResourceRequestInfoImpl* info,
1504 const linked_ptr<ResourceLoader>& loader) { 1508 scoped_ptr<ResourceLoader> loader) {
1505 pending_loaders_[info->GetGlobalRequestID()] = loader; 1509 pending_loaders_[info->GetGlobalRequestID()] = make_linked_ptr(
1506 1510 loader.release());
1507 loader->StartRequest(); 1511 pending_loaders_[info->GetGlobalRequestID()]->ScheduleRequest(
1512 &resource_scheduler_);
1508 } 1513 }
1509 1514
1510 void ResourceDispatcherHostImpl::OnUserGesture(WebContentsImpl* contents) { 1515 void ResourceDispatcherHostImpl::OnUserGesture(WebContentsImpl* contents) {
1511 last_user_gesture_time_ = TimeTicks::Now(); 1516 last_user_gesture_time_ = TimeTicks::Now();
1512 } 1517 }
1513 1518
1514 net::URLRequest* ResourceDispatcherHostImpl::GetURLRequest( 1519 net::URLRequest* ResourceDispatcherHostImpl::GetURLRequest(
1515 const GlobalRequestID& id) { 1520 const GlobalRequestID& id) {
1516 ResourceLoader* loader = GetLoader(id); 1521 ResourceLoader* loader = GetLoader(id);
1517 if (!loader) 1522 if (!loader)
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 return; 1668 return;
1664 } 1669 }
1665 1670
1666 BlockedLoadersList* loaders = iter->second; 1671 BlockedLoadersList* loaders = iter->second;
1667 1672
1668 // Removing the vector from the map unblocks any subsequent requests. 1673 // Removing the vector from the map unblocks any subsequent requests.
1669 blocked_loaders_map_.erase(iter); 1674 blocked_loaders_map_.erase(iter);
1670 1675
1671 for (BlockedLoadersList::iterator loaders_iter = loaders->begin(); 1676 for (BlockedLoadersList::iterator loaders_iter = loaders->begin();
1672 loaders_iter != loaders->end(); ++loaders_iter) { 1677 loaders_iter != loaders->end(); ++loaders_iter) {
1673 linked_ptr<ResourceLoader> loader = *loaders_iter; 1678 scoped_ptr<ResourceLoader> loader(*loaders_iter);
1674 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); 1679 ResourceRequestInfoImpl* info = loader->GetRequestInfo();
1675 if (cancel_requests) { 1680 if (cancel_requests) {
1676 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 1681 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
1677 info->GetChildID()); 1682 info->GetChildID());
1678 } else { 1683 } else {
1679 StartLoading(info, loader); 1684 StartLoading(info, loader.Pass());
1680 } 1685 }
1681 } 1686 }
1682 1687
1688 loaders->weak_erase(loaders->begin(), loaders->end());
1683 delete loaders; 1689 delete loaders;
1684 } 1690 }
1685 1691
1686 ResourceDispatcherHostImpl::HttpAuthResourceType 1692 ResourceDispatcherHostImpl::HttpAuthResourceType
1687 ResourceDispatcherHostImpl::HttpAuthResourceTypeOf(net::URLRequest* request) { 1693 ResourceDispatcherHostImpl::HttpAuthResourceTypeOf(net::URLRequest* request) {
1688 // Use the same critera as for cookies to determine the sub-resource type 1694 // Use the same critera as for cookies to determine the sub-resource type
1689 // that is requesting to be authenticated. 1695 // that is requesting to be authenticated.
1690 if (!request->first_party_for_cookies().is_valid()) 1696 if (!request->first_party_for_cookies().is_valid())
1691 return HTTP_AUTH_RESOURCE_TOP; 1697 return HTTP_AUTH_RESOURCE_TOP;
1692 1698
(...skipping 21 matching lines...) Expand all
1714 const GlobalRequestID& id) const { 1720 const GlobalRequestID& id) const {
1715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1721 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1716 1722
1717 LoaderMap::const_iterator i = pending_loaders_.find(id); 1723 LoaderMap::const_iterator i = pending_loaders_.find(id);
1718 if (i == pending_loaders_.end()) 1724 if (i == pending_loaders_.end())
1719 return NULL; 1725 return NULL;
1720 1726
1721 return i->second.get(); 1727 return i->second.get();
1722 } 1728 }
1723 1729
1724 ResourceLoader* ResourceDispatcherHostImpl::GetLoader(int child_id, 1730 ResourceLoader* ResourceDispatcherHostImpl::GetLoader(
1725 int request_id) const { 1731 int child_id, int request_id) const {
1726 return GetLoader(GlobalRequestID(child_id, request_id)); 1732 return GetLoader(GlobalRequestID(child_id, request_id));
1727 } 1733 }
1728 1734
1729 } // namespace content 1735 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/resource_dispatcher_host_impl.h ('k') | content/browser/renderer_host/resource_loader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698