Chromium Code Reviews| Index: content/browser/loader/resource_dispatcher_host_impl.cc |
| diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc |
| index 839678e30ce5cc01c6e57f60d725d6ef6e196d1b..800637be25d19f746379f23f3dc6c31532c80d33 100644 |
| --- a/content/browser/loader/resource_dispatcher_host_impl.cc |
| +++ b/content/browser/loader/resource_dispatcher_host_impl.cc |
| @@ -127,6 +127,15 @@ const int kUserGestureWindowMs = 3500; |
| // use. Arbitrarily chosen. |
| const double kMaxRequestsPerProcessRatio = 0.45; |
| +bool IsDetachableResourceType(ResourceType::Type type) { |
| + switch (type) { |
| + case ResourceType::PREFETCH: |
| + return true; |
| + default: |
| + return false; |
| + } |
| +} |
| + |
| // Aborts a request before an URLRequest has actually been created. |
| void AbortRequestBeforeItStarts(ResourceMessageFilter* filter, |
| IPC::Message* sync_result, |
| @@ -406,13 +415,16 @@ void ResourceDispatcherHostImpl::CancelRequestsForContext( |
| for (LoaderList::iterator i = loaders_to_cancel.begin(); |
| i != loaders_to_cancel.end(); ++i) { |
| // There is no strict requirement that this be the case, but currently |
| - // downloads, streams and transferred requests are the only requests that |
| - // aren't cancelled when the associated processes go away. It may be OK for |
| - // this invariant to change in the future, but if this assertion fires |
| - // without the invariant changing, then it's indicative of a leak. |
| - DCHECK((*i)->GetRequestInfo()->is_download() || |
| - (*i)->GetRequestInfo()->is_stream() || |
| - (*i)->is_transferring()); |
| + // downloads, streams, detachable requests, and transferred requests are the |
| + // only requests that aren't cancelled when the associated processes go |
| + // away. It may be OK for this invariant to change in the future, but if |
| + // this assertion fires without the invariant changing, then it's indicative |
| + // of a leak. |
| + DCHECK( |
| + (*i)->GetRequestInfo()->is_download() || |
| + (*i)->GetRequestInfo()->is_stream() || |
| + (*i)->GetRequestInfo()->is_detachable() || |
| + (*i)->is_transferring()); |
| } |
| #endif |
| @@ -694,18 +706,19 @@ void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader, |
| void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) { |
| ResourceRequestInfoImpl* info = loader->GetRequestInfo(); |
| + |
| // There should be an entry in the map created when we dispatched the |
| - // request. |
| + // request unless it's been detached and the renderer has died. |
| OfflineMap::iterator policy_it( |
| offline_policy_map_.find(info->GetGlobalRoutingID())); |
| if (offline_policy_map_.end() != policy_it) { |
| policy_it->second->UpdateStateForSuccessfullyStartedRequest( |
| loader->request()->response_info()); |
| } else { |
| - // We should always have an entry in offline_policy_map_ from when |
| - // this request traversed Begin{Download,SaveFile,Request}. |
| + // Unless detachable, we should have an entry in offline_policy_map_ from |
| + // when this request traversed Begin{Download,SaveFile,Request}. |
| // TODO(rdsmith): This isn't currently true; see http://crbug.com/241176. |
| - NOTREACHED(); |
| + DCHECK(info->is_detachable()); |
| } |
| int render_process_id, render_view_id; |
| @@ -1073,6 +1086,7 @@ void ResourceDispatcherHostImpl::BeginRequest( |
| request_data.transition_type, |
| false, // is download |
| false, // is stream |
| + false, // is detachable |
| allow_download, |
| request_data.has_user_gesture, |
| request_data.referrer_policy, |
| @@ -1101,6 +1115,8 @@ void ResourceDispatcherHostImpl::BeginRequest( |
| handler.reset(new SyncResourceHandler(request, sync_result, this)); |
| } else { |
| handler.reset(new AsyncResourceHandler(request, this)); |
| + if (IsDetachableResourceType(request_data.resource_type)) |
| + extra_info->set_is_detachable(true); |
| } |
| // The RedirectToFileResourceHandler depends on being next in the chain. |
| @@ -1219,7 +1235,8 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo( |
| ResourceType::SUB_RESOURCE, |
| PAGE_TRANSITION_LINK, |
| download, // is_download |
| - false, // is_stream |
| + false, // is_stream |
| + false, // is_detachable |
| download, // allow_download |
| false, // has_user_gesture |
| WebKit::WebReferrerPolicyDefault, |
| @@ -1315,8 +1332,8 @@ void ResourceDispatcherHostImpl::ResumeDeferredNavigation( |
| } |
| // The object died, so cancel and detach all requests associated with it except |
| -// for downloads, which belong to the browser process even if initiated via a |
| -// renderer. |
| +// for downloads and detachable resources, which belong to the browser process |
| +// even if initiated via a renderer. |
| void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { |
| CancelRequestsForRoute(child_id, -1 /* cancel all */); |
| registered_temp_files_.erase(child_id); |
| @@ -1341,14 +1358,14 @@ void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id, |
| GlobalRequestID id(child_id, i->first.request_id); |
| DCHECK(id == i->first); |
| - |
| - // Don't cancel navigations that are transferring to another process, |
| - // since they belong to another process now. |
| - if (IsTransferredNavigation(id)) |
| - any_requests_transferring = true; |
| - if (!info->is_download() && !info->is_stream() && |
| - !IsTransferredNavigation(id) && |
| - (route_id == -1 || route_id == info->GetRouteID())) { |
| + // Don't cancel navigations that are expected to live beyond this process. |
| + if (IsTransferredNavigation(id)) any_requests_transferring = true; |
|
James Simonsen
2013/10/26 02:25:00
nit: Split this into 2 lines. This file doesn't us
jkarlin2
2013/10/28 19:25:41
Done.
|
| + |
| + if (info->is_detachable()) { |
| + i->second->CancelAfterTimeout(); |
| + } else if (!info->is_download() && !info->is_stream() && |
| + !IsTransferredNavigation(id) && |
| + (route_id == -1 || route_id == info->GetRouteID())) { |
| matching_requests.push_back(id); |
| } |
| } |