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

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: Resilient to crashing renderers 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 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 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 int child_id = filter_->child_id(); 868 int child_id = filter_->child_id();
868 869
869 // If we crash here, figure out what URL the renderer was requesting. 870 // If we crash here, figure out what URL the renderer was requesting.
870 // http://crbug.com/91398 871 // http://crbug.com/91398
871 char url_buf[128]; 872 char url_buf[128];
872 base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf)); 873 base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf));
873 base::debug::Alias(url_buf); 874 base::debug::Alias(url_buf);
874 875
875 // If the request that's coming in is being transferred from another process, 876 // 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. 877 // we want to reuse and resume the old loader rather than start a new one.
877 linked_ptr<ResourceLoader> deferred_loader; 878 scoped_ptr<ResourceLoader> deferred_loader;
878 { 879 {
879 LoaderMap::iterator it = pending_loaders_.find( 880 LoaderMap::iterator it = pending_loaders_.find(
880 GlobalRequestID(request_data.transferred_request_child_id, 881 GlobalRequestID(request_data.transferred_request_child_id,
881 request_data.transferred_request_request_id)); 882 request_data.transferred_request_request_id));
882 if (it != pending_loaders_.end()) { 883 if (it != pending_loaders_.end()) {
883 if (it->second->is_transferring()) { 884 if (it->second->is_transferring()) {
884 deferred_loader = it->second; 885 deferred_loader.reset(it->second.release());
885 pending_loaders_.erase(it); 886 pending_loaders_.erase(it);
886 } else { 887 } else {
887 RecordAction(UserMetricsAction("BadMessageTerminate_RDH")); 888 RecordAction(UserMetricsAction("BadMessageTerminate_RDH"));
888 filter_->BadMessageReceived(); 889 filter_->BadMessageReceived();
889 return; 890 return;
890 } 891 }
891 } 892 }
892 } 893 }
893 894
894 ResourceContext* resource_context = filter_->resource_context(); 895 ResourceContext* resource_context = filter_->resource_context();
(...skipping 20 matching lines...) Expand all
915 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); 916 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id);
916 return; 917 return;
917 } 918 }
918 919
919 int load_flags = 920 int load_flags =
920 BuildLoadFlagsForRequest(request_data, child_id, sync_result != NULL); 921 BuildLoadFlagsForRequest(request_data, child_id, sync_result != NULL);
921 922
922 // Construct the request. 923 // Construct the request.
923 scoped_ptr<net::URLRequest> new_request; 924 scoped_ptr<net::URLRequest> new_request;
924 net::URLRequest* request; 925 net::URLRequest* request;
925 if (deferred_loader.get()) { 926 if (deferred_loader) {
926 request = deferred_loader->request(); 927 request = deferred_loader->request();
927 928
928 // Give the ResourceLoader (or any of the ResourceHandlers held by it) a 929 // Give the ResourceLoader (or any of the ResourceHandlers held by it) a
929 // chance to reset some state before we complete the transfer. 930 // chance to reset some state before we complete the transfer.
930 deferred_loader->WillCompleteTransfer(); 931 deferred_loader->WillCompleteTransfer();
931 } else { 932 } else {
932 net::URLRequestContext* context = 933 net::URLRequestContext* context =
933 filter_->GetURLRequestContext(request_data.resource_type); 934 filter_->GetURLRequestContext(request_data.resource_type);
934 new_request.reset(context->CreateRequest(request_data.url, NULL)); 935 new_request.reset(context->CreateRequest(request_data.url, NULL));
935 request = new_request.get(); 936 request = new_request.get();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 throttles.begin(), 1050 throttles.begin(),
1050 new TransferNavigationResourceThrottle(request)); 1051 new TransferNavigationResourceThrottle(request));
1051 } 1052 }
1052 1053
1053 if (!throttles.empty()) { 1054 if (!throttles.empty()) {
1054 handler.reset( 1055 handler.reset(
1055 new ThrottlingResourceHandler(handler.Pass(), child_id, request_id, 1056 new ThrottlingResourceHandler(handler.Pass(), child_id, request_id,
1056 throttles.Pass())); 1057 throttles.Pass()));
1057 } 1058 }
1058 1059
1059 if (deferred_loader.get()) { 1060 if (deferred_loader) {
1060 pending_loaders_[extra_info->GetGlobalRequestID()] = deferred_loader; 1061 pending_loaders_[extra_info->GetGlobalRequestID()] = make_linked_ptr(
willchan no longer on Chromium 2012/12/13 06:22:27 linked_ptr--
James Simonsen 2012/12/14 20:23:23 Done. Not convinced this one's a win though. You h
willchan no longer on Chromium 2012/12/14 20:33:32 It's a fair point. I think it's a better state tha
1061 deferred_loader->CompleteTransfer(handler.Pass()); 1062 deferred_loader.release());
1063 pending_loaders_[extra_info->GetGlobalRequestID()]->CompleteTransfer(
1064 handler.Pass());
1062 } else { 1065 } else {
1063 BeginRequestInternal(new_request.Pass(), handler.Pass()); 1066 BeginRequestInternal(new_request.Pass(), handler.Pass());
1064 } 1067 }
1065 } 1068 }
1066 1069
1067 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) { 1070 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) {
1068 UnregisterDownloadedTempFile(filter_->child_id(), request_id); 1071 UnregisterDownloadedTempFile(filter_->child_id(), request_id);
1069 } 1072 }
1070 1073
1071 void ResourceDispatcherHostImpl::OnDataReceivedACK(int request_id) { 1074 void ResourceDispatcherHostImpl::OnDataReceivedACK(int request_id) {
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 } 1481 }
1479 1482
1480 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 1483 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
1481 info->GetChildID()); 1484 info->GetChildID());
1482 1485
1483 // A ResourceHandler must not outlive its associated URLRequest. 1486 // A ResourceHandler must not outlive its associated URLRequest.
1484 handler.reset(); 1487 handler.reset();
1485 return; 1488 return;
1486 } 1489 }
1487 1490
1488 linked_ptr<ResourceLoader> loader( 1491 scoped_ptr<ResourceLoader> loader(
1489 new ResourceLoader(request.Pass(), handler.Pass(), this)); 1492 new ResourceLoader(request.Pass(), handler.Pass(), this));
1490 1493
1491 ProcessRouteIDs pair_id(info->GetChildID(), info->GetRouteID()); 1494 ProcessRouteIDs pair_id(info->GetChildID(), info->GetRouteID());
1492 BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(pair_id); 1495 BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(pair_id);
1493 if (iter != blocked_loaders_map_.end()) { 1496 if (iter != blocked_loaders_map_.end()) {
1494 // The request should be blocked. 1497 // The request should be blocked.
1495 iter->second->push_back(loader); 1498 iter->second->push_back(loader.release());
1496 return; 1499 return;
1497 } 1500 }
1498 1501
1499 StartLoading(info, loader); 1502 StartLoading(info, loader.Pass());
1500 } 1503 }
1501 1504
1502 void ResourceDispatcherHostImpl::StartLoading( 1505 void ResourceDispatcherHostImpl::StartLoading(
1503 ResourceRequestInfoImpl* info, 1506 ResourceRequestInfoImpl* info,
1504 const linked_ptr<ResourceLoader>& loader) { 1507 scoped_ptr<ResourceLoader> loader) {
1505 pending_loaders_[info->GetGlobalRequestID()] = loader; 1508 pending_loaders_[info->GetGlobalRequestID()] = make_linked_ptr(
willchan no longer on Chromium 2012/12/13 06:22:27 linked_ptr--
1506 1509 loader.release());
1507 loader->StartRequest(); 1510 pending_loaders_[info->GetGlobalRequestID()]->ScheduleRequest(
1511 &resource_scheduler_);
1508 } 1512 }
1509 1513
1510 void ResourceDispatcherHostImpl::OnUserGesture(WebContentsImpl* contents) { 1514 void ResourceDispatcherHostImpl::OnUserGesture(WebContentsImpl* contents) {
1511 last_user_gesture_time_ = TimeTicks::Now(); 1515 last_user_gesture_time_ = TimeTicks::Now();
1512 } 1516 }
1513 1517
1514 net::URLRequest* ResourceDispatcherHostImpl::GetURLRequest( 1518 net::URLRequest* ResourceDispatcherHostImpl::GetURLRequest(
1515 const GlobalRequestID& id) { 1519 const GlobalRequestID& id) {
1516 ResourceLoader* loader = GetLoader(id); 1520 ResourceLoader* loader = GetLoader(id);
1517 if (!loader) 1521 if (!loader)
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 return; 1667 return;
1664 } 1668 }
1665 1669
1666 BlockedLoadersList* loaders = iter->second; 1670 BlockedLoadersList* loaders = iter->second;
1667 1671
1668 // Removing the vector from the map unblocks any subsequent requests. 1672 // Removing the vector from the map unblocks any subsequent requests.
1669 blocked_loaders_map_.erase(iter); 1673 blocked_loaders_map_.erase(iter);
1670 1674
1671 for (BlockedLoadersList::iterator loaders_iter = loaders->begin(); 1675 for (BlockedLoadersList::iterator loaders_iter = loaders->begin();
1672 loaders_iter != loaders->end(); ++loaders_iter) { 1676 loaders_iter != loaders->end(); ++loaders_iter) {
1673 linked_ptr<ResourceLoader> loader = *loaders_iter; 1677 scoped_ptr<ResourceLoader> loader(*loaders_iter);
1674 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); 1678 ResourceRequestInfoImpl* info = loader->GetRequestInfo();
1675 if (cancel_requests) { 1679 if (cancel_requests) {
1676 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 1680 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
1677 info->GetChildID()); 1681 info->GetChildID());
1678 } else { 1682 } else {
1679 StartLoading(info, loader); 1683 StartLoading(info, loader.Pass());
1680 } 1684 }
1681 } 1685 }
1682 1686
1687 loaders->weak_erase(loaders->begin(), loaders->end());
1683 delete loaders; 1688 delete loaders;
1684 } 1689 }
1685 1690
1686 ResourceDispatcherHostImpl::HttpAuthResourceType 1691 ResourceDispatcherHostImpl::HttpAuthResourceType
1687 ResourceDispatcherHostImpl::HttpAuthResourceTypeOf(net::URLRequest* request) { 1692 ResourceDispatcherHostImpl::HttpAuthResourceTypeOf(net::URLRequest* request) {
1688 // Use the same critera as for cookies to determine the sub-resource type 1693 // Use the same critera as for cookies to determine the sub-resource type
1689 // that is requesting to be authenticated. 1694 // that is requesting to be authenticated.
1690 if (!request->first_party_for_cookies().is_valid()) 1695 if (!request->first_party_for_cookies().is_valid())
1691 return HTTP_AUTH_RESOURCE_TOP; 1696 return HTTP_AUTH_RESOURCE_TOP;
1692 1697
(...skipping 21 matching lines...) Expand all
1714 const GlobalRequestID& id) const { 1719 const GlobalRequestID& id) const {
1715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1720 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1716 1721
1717 LoaderMap::const_iterator i = pending_loaders_.find(id); 1722 LoaderMap::const_iterator i = pending_loaders_.find(id);
1718 if (i == pending_loaders_.end()) 1723 if (i == pending_loaders_.end())
1719 return NULL; 1724 return NULL;
1720 1725
1721 return i->second.get(); 1726 return i->second.get();
1722 } 1727 }
1723 1728
1724 ResourceLoader* ResourceDispatcherHostImpl::GetLoader(int child_id, 1729 ResourceLoader* ResourceDispatcherHostImpl::GetLoader(
1725 int request_id) const { 1730 int child_id, int request_id) const {
1726 return GetLoader(GlobalRequestID(child_id, request_id)); 1731 return GetLoader(GlobalRequestID(child_id, request_id));
1727 } 1732 }
1728 1733
1729 } // namespace content 1734 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698