Commit 34ca2c89 authored by Yutaka Hirano's avatar Yutaka Hirano Committed by Commit Bot

Put priority information to ResourceLoadScheduler

With this CL, ResourceLoader puts priority information to
ResourceLoadSchedler when RendererSideResourceScheduler feature is
enabled.

Bug: 785770
Change-Id: I4b18df640770e9bc775eae7305d6e858155e82de
Reviewed-on: https://chromium-review.googlesource.com/795632
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarTakashi Toyoshima <toyoshim@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520799}
parent 7a41d355
......@@ -101,6 +101,8 @@ void ResourceLoadScheduler::Shutdown() {
void ResourceLoadScheduler::Request(ResourceLoadSchedulerClient* client,
ThrottleOption option,
ResourceLoadPriority priority,
int intra_priority,
ResourceLoadScheduler::ClientId* id) {
*id = GenerateClientId();
if (is_shutdown_)
......@@ -112,7 +114,10 @@ void ResourceLoadScheduler::Request(ResourceLoadSchedulerClient* client,
}
pending_request_map_.insert(*id, client);
pending_requests_.insert(ClientIdWithPriority(*id));
if (Platform::Current()->IsRendererSideResourceSchedulerEnabled())
pending_requests_.emplace(*id, priority, intra_priority);
else
pending_requests_.emplace(*id);
MaybeRun();
}
......@@ -202,6 +207,26 @@ void ResourceLoadScheduler::OnNetworkQuiet() {
}
}
ResourceLoadScheduler::ThrottleOption ResourceLoadScheduler::CanThrottle(
const ResourceRequest& request,
SynchronousPolicy synchronous_policy) const {
// Synchronous requests should not work with a throttling. Also, tentatively
// disables throttling for fetch requests that could keep on holding an active
// connection until data is read by JavaScript.
if (synchronous_policy == kRequestSynchronously)
return ResourceLoadScheduler::ThrottleOption::kCanNotBeThrottled;
if (request.GetRequestContext() == WebURLRequest::kRequestContextFetch)
return ResourceLoadScheduler::ThrottleOption::kCanNotBeThrottled;
if (Platform::Current()->IsRendererSideResourceSchedulerEnabled()) {
if (request.Priority() >= ResourceLoadPriority::kMedium)
return ResourceLoadScheduler::ThrottleOption::kCanNotBeThrottled;
}
return ResourceLoadScheduler::ThrottleOption::kCanBeThrottled;
}
void ResourceLoadScheduler::OnThrottlingStateChanged(
WebFrameScheduler::ThrottlingState state) {
switch (state) {
......
......@@ -11,6 +11,7 @@
#include "platform/heap/HeapAllocator.h"
#include "platform/loader/fetch/FetchContext.h"
#include "platform/loader/fetch/Resource.h"
#include "platform/loader/fetch/ResourceLoaderOptions.h"
#include "platform/wtf/HashSet.h"
namespace blink {
......@@ -74,7 +75,11 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
// ResourceLoadSchedulerClient::Run(), but it is guaranteed that ClientId is
// populated before ResourceLoadSchedulerClient::Run() is called, so that the
// caller can call Release() with the assigned ClientId correctly.
void Request(ResourceLoadSchedulerClient*, ThrottleOption, ClientId*);
void Request(ResourceLoadSchedulerClient*,
ThrottleOption,
ResourceLoadPriority,
int intra_priority,
ClientId*);
// ResourceLoadSchedulerClient should call this method when the loading is
// finished, or canceled. This method can be called in a pre-finalization
......@@ -86,12 +91,26 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
void OnNetworkQuiet();
// Returns whether we can throttle the given request.
ThrottleOption CanThrottle(const ResourceRequest&, SynchronousPolicy) const;
// WebFrameScheduler::Observer overrides:
void OnThrottlingStateChanged(WebFrameScheduler::ThrottlingState) override;
private:
class ClientIdWithPriority {
public:
struct Compare {
bool operator()(const ClientIdWithPriority& x,
const ClientIdWithPriority& y) const {
if (x.priority != y.priority)
return x.priority > y.priority;
if (x.intra_priority != y.intra_priority)
return x.intra_priority > y.intra_priority;
return x.client_id < y.client_id;
}
};
ClientIdWithPriority(ClientId client_id,
WebURLRequest::Priority priority,
int intra_priority)
......@@ -103,14 +122,6 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
WebURLRequest::Priority::kUnresolved,
0) {}
bool operator<(const ClientIdWithPriority& other) const {
if (priority != other.priority)
return priority < other.priority;
if (intra_priority != other.intra_priority)
return intra_priority < other.intra_priority;
return client_id < other.client_id;
}
const ClientId client_id;
const WebURLRequest::Priority priority;
const int intra_priority;
......@@ -167,7 +178,8 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
HeapHashMap<ClientId, Member<ResourceLoadSchedulerClient>>
pending_request_map_;
// We use std::set here because WTF doesn't have its counterpart.
std::set<ClientIdWithPriority> pending_requests_;
std::set<ClientIdWithPriority, ClientIdWithPriority::Compare>
pending_requests_;
// Holds FetchContext reference to contact WebFrameScheduler.
Member<FetchContext> context_;
......
......@@ -102,17 +102,12 @@ void ResourceLoader::Start() {
ActivateCacheAwareLoadingIfNeeded(request);
loader_ =
Context().CreateURLLoader(request, GetTaskRunnerFor(request, Context()));
// Synchronous requests should not work with a throttling. Also, tentatively
// disables throttling for fetch requests that could keep on holding an active
// connection until data is read by JavaScript.
ResourceLoadScheduler::ThrottleOption option =
(resource_->Options().synchronous_policy == kRequestSynchronously ||
request.GetRequestContext() == WebURLRequest::kRequestContextFetch)
? ResourceLoadScheduler::ThrottleOption::kCanNotBeThrottled
: ResourceLoadScheduler::ThrottleOption::kCanBeThrottled;
DCHECK_EQ(ResourceLoadScheduler::kInvalidClientId, scheduler_client_id_);
scheduler_->Request(this, option, &scheduler_client_id_);
const auto throttle_option =
scheduler_->CanThrottle(request, resource_->Options().synchronous_policy);
scheduler_->Request(this, throttle_option, request.Priority(),
request.IntraPriorityValue(), &scheduler_client_id_);
}
void ResourceLoader::Run() {
......
......@@ -351,6 +351,10 @@ ResourceLoadPriority ResourceRequest::Priority() const {
return priority_;
}
int ResourceRequest::IntraPriorityValue() const {
return intra_priority_value_;
}
void ResourceRequest::SetPriority(ResourceLoadPriority priority,
int intra_priority_value) {
priority_ = priority;
......
......@@ -178,7 +178,9 @@ class PLATFORM_EXPORT ResourceRequest final {
bool AllowStoredCredentials() const;
void SetAllowStoredCredentials(bool allow_credentials);
// TODO(yhirano): Describe what Priority and IntraPriorityValue are.
ResourceLoadPriority Priority() const;
int IntraPriorityValue() const;
void SetPriority(ResourceLoadPriority, int intra_priority_value = 0);
bool IsConditional() const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment