| Index: content/browser/loader/resource_scheduler.cc
|
| diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc
|
| index cdd5867c0ad4b2f5a73f37f37820048ed893c33e..0a171ad06923cbadc9d9dad2704a5fc84c34fb8a 100644
|
| --- a/content/browser/loader/resource_scheduler.cc
|
| +++ b/content/browser/loader/resource_scheduler.cc
|
| @@ -16,9 +16,6 @@
|
|
|
| namespace content {
|
|
|
| -// TODO(simonjam): This is arbitrary. Experiment.
|
| -static const int kMaxNumNavigationsToTrack = 5;
|
| -
|
| class ResourceScheduler::ScheduledResourceRequest
|
| : public ResourceMessageDelegate,
|
| public ResourceThrottle {
|
| @@ -83,8 +80,7 @@ class ResourceScheduler::ScheduledResourceRequest
|
| DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest);
|
| };
|
|
|
| -ResourceScheduler::ResourceScheduler()
|
| - : client_map_(kMaxNumNavigationsToTrack) {
|
| +ResourceScheduler::ResourceScheduler() {
|
| }
|
|
|
| ResourceScheduler::~ResourceScheduler() {
|
| @@ -94,6 +90,7 @@ ResourceScheduler::~ResourceScheduler() {
|
| DCHECK(it->second->in_flight_requests.empty());
|
| }
|
| DCHECK(unowned_requests_.empty());
|
| + DCHECK(client_map_.empty());
|
| }
|
|
|
| scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest(
|
| @@ -105,13 +102,12 @@ scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest(
|
| scoped_ptr<ScheduledResourceRequest> request(
|
| new ScheduledResourceRequest(client_id, url_request, this));
|
|
|
| - ClientMap::iterator it = client_map_.Get(client_id);
|
| + ClientMap::iterator it = client_map_.find(client_id);
|
| if (it == client_map_.end()) {
|
| // There are several ways this could happen:
|
| // 1. <a ping> requests don't have a route_id.
|
| // 2. Most unittests don't send the IPCs needed to register Clients.
|
| // 3. The tab is closed while a RequestResource IPC is in flight.
|
| - // 4. The tab hasn't navigated recently.
|
| unowned_requests_.insert(request.get());
|
| request->Start();
|
| return request.PassAs<ResourceThrottle>();
|
| @@ -140,7 +136,7 @@ void ResourceScheduler::RemoveRequest(ScheduledResourceRequest* request) {
|
| return;
|
| }
|
|
|
| - ClientMap::iterator client_it = client_map_.Get(request->client_id());
|
| + ClientMap::iterator client_it = client_map_.find(request->client_id());
|
| if (client_it == client_map_.end()) {
|
| return;
|
| }
|
| @@ -172,13 +168,42 @@ void ResourceScheduler::RemoveRequest(ScheduledResourceRequest* request) {
|
| }
|
| }
|
|
|
| +void ResourceScheduler::OnClientCreated(int child_id, int route_id) {
|
| + DCHECK(CalledOnValidThread());
|
| + ClientId client_id = MakeClientId(child_id, route_id);
|
| + DCHECK(!ContainsKey(client_map_, client_id));
|
| +
|
| + client_map_[client_id] = new Client;
|
| +}
|
| +
|
| +void ResourceScheduler::OnClientDeleted(int child_id, int route_id) {
|
| + DCHECK(CalledOnValidThread());
|
| + ClientId client_id = MakeClientId(child_id, route_id);
|
| + DCHECK(ContainsKey(client_map_, client_id));
|
| + ClientMap::iterator it = client_map_.find(client_id);
|
| + Client* client = it->second;
|
| +
|
| + // FYI, ResourceDispatcherHost cancels all of the requests after this function
|
| + // is called. It should end up canceling all of the requests except for a
|
| + // cross-renderer navigation.
|
| + for (RequestSet::iterator it = client->in_flight_requests.begin();
|
| + it != client->in_flight_requests.end(); ++it) {
|
| + unowned_requests_.insert(*it);
|
| + }
|
| + client->in_flight_requests.clear();
|
| +
|
| + delete client;
|
| + client_map_.erase(it);
|
| +}
|
| +
|
| void ResourceScheduler::OnNavigate(int child_id, int route_id) {
|
| DCHECK(CalledOnValidThread());
|
| ClientId client_id = MakeClientId(child_id, route_id);
|
|
|
| - ClientMap::iterator it = client_map_.Get(client_id);
|
| + ClientMap::iterator it = client_map_.find(client_id);
|
| if (it == client_map_.end()) {
|
| - it = client_map_.Put(client_id, new Client(this));
|
| + // The client was likely deleted shortly before we received this IPC.
|
| + return;
|
| }
|
|
|
| Client* client = it->second;
|
| @@ -188,12 +213,15 @@ void ResourceScheduler::OnNavigate(int child_id, int route_id) {
|
| void ResourceScheduler::OnWillInsertBody(int child_id, int route_id) {
|
| DCHECK(CalledOnValidThread());
|
| ClientId client_id = MakeClientId(child_id, route_id);
|
| - ClientMap::iterator it = client_map_.Get(client_id);
|
| +
|
| + ClientMap::iterator it = client_map_.find(client_id);
|
| if (it == client_map_.end()) {
|
| + // The client was likely deleted shortly before we received this IPC.
|
| return;
|
| }
|
|
|
| Client* client = it->second;
|
| + client->has_body = false;
|
| if (!client->has_body) {
|
| client->has_body = true;
|
| LoadPendingRequests(client);
|
| @@ -214,29 +242,16 @@ void ResourceScheduler::LoadPendingRequests(Client* client) {
|
| }
|
| }
|
|
|
| -void ResourceScheduler::RemoveClient(Client* client) {
|
| - LoadPendingRequests(client);
|
| - for (RequestSet::iterator it = client->in_flight_requests.begin();
|
| - it != client->in_flight_requests.end(); ++it) {
|
| - unowned_requests_.insert(*it);
|
| - }
|
| - client->in_flight_requests.clear();
|
| -}
|
| -
|
| ResourceScheduler::ClientId ResourceScheduler::MakeClientId(
|
| int child_id, int route_id) {
|
| return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
|
| }
|
|
|
| -ResourceScheduler::Client::Client(ResourceScheduler* scheduler)
|
| - : has_body(false),
|
| - scheduler_(scheduler) {
|
| +ResourceScheduler::Client::Client()
|
| + : has_body(false) {
|
| }
|
|
|
| ResourceScheduler::Client::~Client() {
|
| - scheduler_->RemoveClient(this);
|
| - DCHECK(in_flight_requests.empty());
|
| - DCHECK(pending_requests.empty());
|
| }
|
|
|
| } // namespace content
|
|
|