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 6cc7f6196f95a3832224a5332cb20df0b113cf6c..4984c6e81c78a0f17912e31a92f10757bb9d14a2 100644 |
| --- a/content/browser/loader/resource_dispatcher_host_impl.cc |
| +++ b/content/browser/loader/resource_dispatcher_host_impl.cc |
| @@ -19,6 +19,7 @@ |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/shared_memory.h" |
| #include "base/message_loop/message_loop.h" |
| +#include "base/metrics/field_trial.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "base/metrics/sparse_histogram.h" |
| #include "base/profiler/scoped_tracker.h" |
| @@ -473,10 +474,19 @@ ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() |
| update_load_states_timer_.reset( |
| new base::RepeatingTimer<ResourceDispatcherHostImpl>()); |
| + |
| + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| + if (base::FieldTrialList::FindFullName("StaleWhileRevalidate") == "Enabled" || |
| + command_line->HasSwitch(switches::kEnableStaleWhileRevalidate)) { |
| + async_revalidation_manager_.reset(new AsyncRevalidationManager); |
| + } |
| } |
| ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { |
| DCHECK(outstanding_requests_stats_map_.empty()); |
| + // It's not safe to destroy this object while AsyncRevalidationDriver objects |
| + // have callbacks referencing it. |
| + async_revalidation_manager_.reset(); |
| DCHECK(g_resource_dispatcher_host); |
| g_resource_dispatcher_host = NULL; |
| } |
| @@ -578,6 +588,13 @@ void ResourceDispatcherHostImpl::CancelRequestsForContext( |
| loaders_to_cancel.clear(); |
| + if (async_revalidation_manager_) { |
| + // Cancelling async revalidations should not result in the creation of new |
| + // requests, but do it before the checks just to be on the safe side. |
| + async_revalidation_manager_->CancelAsyncRevalidationsForResourceContext( |
| + context); |
| + } |
| + |
| // Validate that no more requests for this context were added. |
| for (LoaderMap::const_iterator i = pending_loaders_.begin(); |
| i != pending_loaders_.end(); ++i) { |
| @@ -824,6 +841,14 @@ void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader, |
| if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) |
| return; |
| + // Remove the LOAD_SUPPORT_ASYNC_REVALIDATION flag if it is present. |
|
Bence
2015/11/17 13:12:23
Please explain briefly why you do this for redirec
Adam Rice
2015/11/17 17:45:53
Done.
|
| + net::URLRequest* request = loader->request(); |
| + if (request->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION) { |
| + int new_load_flags = request->load_flags() & |
| + ~net::LOAD_SUPPORT_ASYNC_REVALIDATION; |
| + request->SetLoadFlags(new_load_flags); |
| + } |
| + |
| // Notify the observers on the UI thread. |
| scoped_ptr<ResourceRedirectDetails> detail(new ResourceRedirectDetails( |
| loader->request(), |
| @@ -846,6 +871,12 @@ void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) { |
| info->GetChildID(), info->GetRouteID()); |
| } |
| + if (request->response_info().async_revalidation_required && !is_shutdown_) { |
| + DCHECK(async_revalidation_manager_); |
| + async_revalidation_manager_->BeginAsyncRevalidation(request, |
| + scheduler_.get()); |
| + } |
| + |
| int render_process_id, render_frame_host; |
| if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) |
| return; |
| @@ -1279,6 +1310,14 @@ void ResourceDispatcherHostImpl::BeginRequest( |
| load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; |
| } |
| + // Check if request is eligible for async revalidation. |
|
Bence
2015/11/17 13:12:23
Optional: this comment seems to be redundant with
Adam Rice
2015/11/17 17:45:53
Done.
|
| + bool support_async_revalidation = |
| + (!is_sync_load && async_revalidation_manager_ && |
| + AsyncRevalidationManager::QualifiesForAsyncRevalidation(request_data)); |
| + |
| + if (support_async_revalidation) |
| + load_flags |= net::LOAD_SUPPORT_ASYNC_REVALIDATION; |
| + |
| // Sync loads should have maximum priority and should be the only |
| // requets that have the ignore limits flag set. |
| if (is_sync_load) { |
| @@ -1312,7 +1351,8 @@ void ResourceDispatcherHostImpl::BeginRequest( |
| request_data.referrer_policy, |
| request_data.visiblity_state, |
| resource_context, filter_->GetWeakPtr(), |
| - !is_sync_load); |
| + !is_sync_load, |
| + support_async_revalidation ? request_data.headers : std::string()); |
| // Request takes ownership. |
| extra_info->AssociateWithRequest(new_request.get()); |
| @@ -1583,7 +1623,8 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo( |
| blink::WebPageVisibilityStateVisible, |
| context, |
| base::WeakPtr<ResourceMessageFilter>(), // filter |
| - true); // is_async |
| + true, // is_async |
| + std::string()); // original_headers |
| } |
| void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id, |
| @@ -2026,7 +2067,8 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( |
| blink::WebPageVisibilityStateVisible, |
| resource_context, |
| base::WeakPtr<ResourceMessageFilter>(), // filter |
| - true); |
| + true, // is_async |
| + std::string()); // original_headers |
| // Request takes ownership. |
| extra_info->AssociateWithRequest(new_request.get()); |
| @@ -2060,6 +2102,12 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( |
| BeginRequestInternal(new_request.Pass(), handler.Pass()); |
| } |
| +void ResourceDispatcherHostImpl::EnableStaleWhileRevalidateForTesting() { |
| + // Do nothing if it is enabled already. |
| + if (!async_revalidation_manager_) |
| + async_revalidation_manager_.reset(new AsyncRevalidationManager); |
| +} |
| + |
| // static |
| int ResourceDispatcherHostImpl::CalculateApproximateMemoryCost( |
| net::URLRequest* request) { |