Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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()); | |
|
willchan no longer on Chromium
2012/12/13 06:30:43
Why not weak_clear()?
James Simonsen
2012/12/14 20:23:23
Didn't know about it. Done.
| |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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( |
| 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 Loading... | |
| 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( |
| 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 Loading... | |
| 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; |
|
willchan no longer on Chromium
2012/12/13 06:30:43
weak_clear?
James Simonsen
2012/12/14 20:23:23
Done.
| |
| 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 |
| 1693 if (net::RegistryControlledDomainService::SameDomainOrHost( | 1698 if (net::RegistryControlledDomainService::SameDomainOrHost( |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 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 |
| OLD | NEW |