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/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 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()); | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |