Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1005)

Unified Diff: content/browser/loader/resource_scheduler.cc

Issue 12874003: Limit to only 10 image requests per page in ResourceScheduler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/loader/resource_scheduler.cc
diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc
index ef95f2a34f9cb79b962246ed847e81e70f2ef110..8d510f34849a8d4049523f2cdf6f7bd42566a3af 100644
--- a/content/browser/loader/resource_scheduler.cc
+++ b/content/browser/loader/resource_scheduler.cc
@@ -16,6 +16,8 @@
namespace content {
+static const int kMaxNumLowPriorityRequestsPerClient = 10;
+
class ResourceScheduler::ScheduledResourceRequest
: public ResourceMessageDelegate,
public ResourceThrottle {
@@ -43,6 +45,18 @@ class ResourceScheduler::ScheduledResourceRequest
}
}
+ // |queue_pointer| keeps track of the position of |this| in its client's
+ // |pending_requests| queue.
+ ResourceScheduler::RequestQueue::Pointer queue_pointer() {
+ return queue_pointer_;
+ }
+ void set_queue_pointer(ResourceScheduler::RequestQueue::Pointer pointer) {
+ queue_pointer_ = pointer;
+ }
+ void clear_queue_pointer() {
+ queue_pointer_.Reset();
+ }
+
const ClientId& client_id() const { return client_id_; }
const net::URLRequest& url_request() const { return *request_; }
@@ -65,9 +79,9 @@ class ResourceScheduler::ScheduledResourceRequest
void DidChangePriority(int request_id, net::RequestPriority new_priority) {
net::RequestPriority old_priority = request_->priority();
- request_->set_priority(new_priority);
- if (new_priority > old_priority) {
- Start();
+ if (new_priority != old_priority) {
willchan no longer on Chromium 2013/03/18 07:30:33 When is this ever false? Sounds like a renderer bu
James Simonsen 2013/03/18 23:50:13 Agreed. Done.
+ request_->set_priority(new_priority);
+ scheduler_->ReprioritizeRequest(this);
}
}
@@ -76,6 +90,7 @@ class ResourceScheduler::ScheduledResourceRequest
bool ready_;
bool deferred_;
ResourceScheduler* scheduler_;
+ ResourceScheduler::RequestQueue::Pointer queue_pointer_;
DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest);
};
@@ -86,7 +101,7 @@ ResourceScheduler::ResourceScheduler() {
ResourceScheduler::~ResourceScheduler() {
for (ClientMap::iterator it ALLOW_UNUSED = client_map_.begin();
it != client_map_.end(); ++it) {
- DCHECK(it->second->pending_requests.empty());
+ DCHECK(!it->second->pending_requests.size());
DCHECK(it->second->in_flight_requests.empty());
}
DCHECK(unowned_requests_.empty());
@@ -114,17 +129,12 @@ scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest(
}
Client* client = it->second;
-
- bool is_synchronous = (url_request->load_flags() & net::LOAD_IGNORE_LIMITS) ==
- net::LOAD_IGNORE_LIMITS;
- bool is_low_priority =
- url_request->priority() < net::LOW && !is_synchronous;
-
- if (is_low_priority && !client->in_flight_requests.empty() &&
- !client->has_body) {
- client->pending_requests.push_back(request.get());
- } else {
+ if (ShouldStartRequest(request.get(), client)) {
StartRequest(request.get(), client);
+ } else {
+ RequestQueue::Pointer pointer = client->pending_requests.Insert(
+ request.get(), url_request->priority());
+ request->set_queue_pointer(pointer);
}
return request.PassAs<ResourceThrottle>();
}
@@ -142,30 +152,18 @@ void ResourceScheduler::RemoveRequest(ScheduledResourceRequest* request) {
}
Client* client = client_it->second;
- RequestSet::iterator request_it = client->in_flight_requests.find(request);
- if (request_it == client->in_flight_requests.end()) {
- bool removed = false;
- RequestQueue::iterator queue_it;
- for (queue_it = client->pending_requests.begin();
- queue_it != client->pending_requests.end(); ++queue_it) {
- if (*queue_it == request) {
- client->pending_requests.erase(queue_it);
- removed = true;
- break;
- }
- }
- DCHECK(removed);
- DCHECK(!ContainsKey(client->in_flight_requests, request));
- } else {
+
+ if (request->queue_pointer().is_null()) {
size_t erased = client->in_flight_requests.erase(request);
DCHECK(erased);
+ } else {
+ client->pending_requests.Erase(request->queue_pointer());
+ request->clear_queue_pointer();
+ DCHECK(!ContainsKey(client->in_flight_requests, request));
}
- if (client->in_flight_requests.empty()) {
- // Since the network is now idle, we may as well load some of the low
- // priority requests.
- LoadPendingRequests(client);
- }
+ // Removing this request may have freed up another to load.
willchan no longer on Chromium 2013/03/18 07:30:33 Isn't this only true if we remove an in flight req
James Simonsen 2013/03/18 23:50:13 Done.
+ LoadPendingRequests(client);
}
void ResourceScheduler::OnClientCreated(int child_id, int route_id) {
@@ -233,26 +231,93 @@ void ResourceScheduler::StartRequest(ScheduledResourceRequest* request,
request->Start();
}
+void ResourceScheduler::ReprioritizeRequest(ScheduledResourceRequest* request) {
+ ClientMap::iterator client_it = client_map_.find(request->client_id());
+ if (client_it == client_map_.end()) {
+ // The client was likely deleted shortly before we received this IPC.
willchan no longer on Chromium 2013/03/18 07:30:33 How? The comment for OnClientDeleted() says it hap
James Simonsen 2013/03/18 23:50:13 RenderViewHosts can be deleted by user action on t
willchan no longer on Chromium 2013/03/19 20:53:52 Why are we listening for the signal that the Rende
+ return;
+ }
+
+ Client *client = client_it->second;
+ if (request->queue_pointer().is_null()) {
+ DCHECK(ContainsKey(client->in_flight_requests, request));
+ // Request has already started.
willchan no longer on Chromium 2013/03/18 07:30:33 But don't we need to call set_priority()? OH, I se
James Simonsen 2013/03/18 23:50:13 Done.
+ return;
+ }
+
+ client->pending_requests.Erase(request->queue_pointer());
willchan no longer on Chromium 2013/03/18 07:30:33 When I see stuff like this where the caller needs
James Simonsen 2013/03/18 23:50:13 Done.
+ RequestQueue::Pointer pointer = client->pending_requests.Insert(
+ request, request->url_request().priority());
+ request->set_queue_pointer(pointer);
+
+ // Check if this request is now able to load at its new priority.
willchan no longer on Chromium 2013/03/18 07:30:33 We only want to do this if the new priority is hig
James Simonsen 2013/03/18 23:50:13 Done.
+ LoadPendingRequests(client);
+}
+
void ResourceScheduler::LoadPendingRequests(Client* client) {
- while (!client->pending_requests.empty()) {
- ScheduledResourceRequest* request = client->pending_requests.front();
- client->pending_requests.erase(client->pending_requests.begin());
- StartRequest(request, client);
+ while (client->pending_requests.size()) {
+ ScheduledResourceRequest* request =
+ client->pending_requests.FirstMax().value();
+ if (ShouldStartRequest(request, client)) {
+ client->pending_requests.Erase(request->queue_pointer());
+ request->clear_queue_pointer();
+ StartRequest(request, client);
+ } else {
+ break;
+ }
}
}
+int ResourceScheduler::GetNumLowPriorityRequestsInFlight(Client* client) {
+ int count = 0;
+ for (RequestSet::iterator it = client->in_flight_requests.begin();
+ it != client->in_flight_requests.end(); ++it) {
+ if ((*it)->url_request().priority() < net::LOW) {
+ ++count;
+ }
+ }
+ return count;
+}
+
+bool ResourceScheduler::ShouldStartRequest(ScheduledResourceRequest* request,
willchan no longer on Chromium 2013/03/18 07:30:33 Please add a comment here explaining in plain Engl
James Simonsen 2013/03/18 23:50:13 Done.
+ Client* client) {
+ bool is_synchronous =
willchan no longer on Chromium 2013/03/18 07:30:33 I know you're just moving this, but this caught my
James Simonsen 2013/03/18 23:50:13 Done.
+ (request->url_request().load_flags() & net::LOAD_IGNORE_LIMITS) ==
+ net::LOAD_IGNORE_LIMITS;
+ bool is_low_priority =
willchan no longer on Chromium 2013/03/18 07:30:33 Sorry again for nitting you when you're just movin
James Simonsen 2013/03/18 23:50:13 Done.
+ request->url_request().priority() < net::LOW && !is_synchronous;
+ if (!is_low_priority)
+ return true;
+
+ int num_low_priority_requests_in_flight =
+ GetNumLowPriorityRequestsInFlight(client);
+ if (num_low_priority_requests_in_flight >=
+ kMaxNumLowPriorityRequestsPerClient) {
+ return false;
+ }
+
+ int num_high_priority_requests_in_flight =
willchan no longer on Chromium 2013/03/18 07:30:33 You don't need the number, you just need to know i
James Simonsen 2013/03/18 23:50:13 Done.
+ client->in_flight_requests.size() - num_low_priority_requests_in_flight;
+ if (num_high_priority_requests_in_flight && !client->has_body) {
+ return false;
+ }
+
+ return true;
+}
+
ResourceScheduler::ClientId ResourceScheduler::MakeClientId(
int child_id, int route_id) {
return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
}
ResourceScheduler::Client::Client()
- : has_body(false) {
+ : has_body(false),
+ pending_requests(net::NUM_PRIORITIES) {
}
ResourceScheduler::Client::~Client() {
DCHECK(in_flight_requests.empty());
- DCHECK(pending_requests.empty());
+ DCHECK(!pending_requests.size());
}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698