OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading | 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | 9 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
10 | 10 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 safe_browsing_(new SafeBrowsingService), | 129 safe_browsing_(new SafeBrowsingService), |
130 request_id_(-1), | 130 request_id_(-1), |
131 plugin_service_(PluginService::GetInstance()), | 131 plugin_service_(PluginService::GetInstance()), |
132 method_runner_(this), | 132 method_runner_(this), |
133 is_shutdown_(false) { | 133 is_shutdown_(false) { |
134 } | 134 } |
135 | 135 |
136 ResourceDispatcherHost::~ResourceDispatcherHost() { | 136 ResourceDispatcherHost::~ResourceDispatcherHost() { |
137 AsyncResourceHandler::GlobalCleanup(); | 137 AsyncResourceHandler::GlobalCleanup(); |
138 STLDeleteValues(&pending_requests_); | 138 STLDeleteValues(&pending_requests_); |
| 139 |
| 140 // Clear blocked requests if any left. |
| 141 // Note that we have to do this in 2 passes as we cannot call |
| 142 // CancelBlockedRequestsForRenderView while iterating over |
| 143 // blocked_requests_map_, as it modifies it. |
| 144 std::set<ProcessRendererIDs> ids; |
| 145 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin(); |
| 146 iter != blocked_requests_map_.end(); ++iter) { |
| 147 std::pair<std::set<ProcessRendererIDs>::iterator, bool> result = |
| 148 ids.insert(iter->first); |
| 149 // We should not have duplicates. |
| 150 DCHECK(result.second); |
| 151 } |
| 152 for (std::set<ProcessRendererIDs>::const_iterator iter = ids.begin(); |
| 153 iter != ids.end(); ++iter) { |
| 154 CancelBlockedRequestsForRenderView(iter->first, iter->second); |
| 155 } |
139 } | 156 } |
140 | 157 |
141 void ResourceDispatcherHost::Initialize() { | 158 void ResourceDispatcherHost::Initialize() { |
142 DCHECK(MessageLoop::current() == ui_loop_); | 159 DCHECK(MessageLoop::current() == ui_loop_); |
143 download_file_manager_->Initialize(); | 160 download_file_manager_->Initialize(); |
144 safe_browsing_->Initialize(io_loop_); | 161 safe_browsing_->Initialize(io_loop_); |
145 } | 162 } |
146 | 163 |
147 void ResourceDispatcherHost::Shutdown() { | 164 void ResourceDispatcherHost::Shutdown() { |
148 DCHECK(MessageLoop::current() == ui_loop_); | 165 DCHECK(MessageLoop::current() == ui_loop_); |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 // matching_requests, it is normal for a matching request to be not found | 621 // matching_requests, it is normal for a matching request to be not found |
605 // in pending_requests_ after we have removed some matching requests from | 622 // in pending_requests_ after we have removed some matching requests from |
606 // pending_requests_. For example, deleting a URLRequest that has | 623 // pending_requests_. For example, deleting a URLRequest that has |
607 // exclusive (write) access to an HTTP cache entry may unblock another | 624 // exclusive (write) access to an HTTP cache entry may unblock another |
608 // URLRequest that needs exclusive access to the same cache entry, and | 625 // URLRequest that needs exclusive access to the same cache entry, and |
609 // that URLRequest may complete and remove itself from pending_requests_. | 626 // that URLRequest may complete and remove itself from pending_requests_. |
610 // So we need to check that iter is not equal to pending_requests_.end(). | 627 // So we need to check that iter is not equal to pending_requests_.end(). |
611 if (iter != pending_requests_.end()) | 628 if (iter != pending_requests_.end()) |
612 RemovePendingRequest(iter); | 629 RemovePendingRequest(iter); |
613 } | 630 } |
| 631 |
| 632 // Now deal with blocked requests if any. |
| 633 if (render_view_id != -1) { |
| 634 if (blocked_requests_map_.find(std::pair<int, int>(render_process_host_id, |
| 635 render_view_id)) != |
| 636 blocked_requests_map_.end()) { |
| 637 CancelBlockedRequestsForRenderView(render_process_host_id, |
| 638 render_view_id); |
| 639 } |
| 640 } else { |
| 641 // We have to do all render views for the process |render_process_host_id|. |
| 642 // Note that we have to do this in 2 passes as we cannot call |
| 643 // CancelBlockedRequestsForRenderView while iterating over |
| 644 // blocked_requests_map_, as it modifies it. |
| 645 std::set<int> render_view_ids; |
| 646 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin(); |
| 647 iter != blocked_requests_map_.end(); ++iter) { |
| 648 if (iter->first.first == render_process_host_id) |
| 649 render_view_ids.insert(iter->first.second); |
| 650 } |
| 651 for (std::set<int>::const_iterator iter = render_view_ids.begin(); |
| 652 iter != render_view_ids.end(); ++iter) { |
| 653 CancelBlockedRequestsForRenderView(render_process_host_id, *iter); |
| 654 } |
| 655 } |
614 } | 656 } |
615 | 657 |
616 // Cancels the request and removes it from the list. | 658 // Cancels the request and removes it from the list. |
617 void ResourceDispatcherHost::RemovePendingRequest(int render_process_host_id, | 659 void ResourceDispatcherHost::RemovePendingRequest(int render_process_host_id, |
618 int request_id) { | 660 int request_id) { |
619 PendingRequestList::iterator i = pending_requests_.find( | 661 PendingRequestList::iterator i = pending_requests_.find( |
620 GlobalRequestID(render_process_host_id, request_id)); | 662 GlobalRequestID(render_process_host_id, request_id)); |
621 if (i == pending_requests_.end()) { | 663 if (i == pending_requests_.end()) { |
622 NOTREACHED() << "Trying to remove a request that's not here"; | 664 NOTREACHED() << "Trying to remove a request that's not here"; |
623 return; | 665 return; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 } | 814 } |
773 | 815 |
774 NotifyResponseStarted(request, info->render_process_host_id); | 816 NotifyResponseStarted(request, info->render_process_host_id); |
775 return info->resource_handler->OnResponseStarted(info->request_id, | 817 return info->resource_handler->OnResponseStarted(info->request_id, |
776 response.get()); | 818 response.get()); |
777 } | 819 } |
778 | 820 |
779 void ResourceDispatcherHost::BeginRequestInternal(URLRequest* request, | 821 void ResourceDispatcherHost::BeginRequestInternal(URLRequest* request, |
780 bool mixed_content) { | 822 bool mixed_content) { |
781 ExtraRequestInfo* info = ExtraInfoForRequest(request); | 823 ExtraRequestInfo* info = ExtraInfoForRequest(request); |
| 824 |
| 825 std::pair<int, int> pair_id(info->render_process_host_id, |
| 826 info->render_view_id); |
| 827 BlockedRequestMap::const_iterator iter = blocked_requests_map_.find(pair_id); |
| 828 if (iter != blocked_requests_map_.end()) { |
| 829 // The request should be blocked. |
| 830 iter->second->push_back(BlockedRequest(request, mixed_content)); |
| 831 return; |
| 832 } |
| 833 |
782 GlobalRequestID global_id(info->render_process_host_id, info->request_id); | 834 GlobalRequestID global_id(info->render_process_host_id, info->request_id); |
783 pending_requests_[global_id] = request; | 835 pending_requests_[global_id] = request; |
784 if (mixed_content) { | 836 if (mixed_content) { |
785 // We don't start the request in that case. The SSLManager will potentially | 837 // We don't start the request in that case. The SSLManager will potentially |
786 // change the request (potentially to indicate its content should be | 838 // change the request (potentially to indicate its content should be |
787 // filtered) and start it itself. | 839 // filtered) and start it itself. |
788 SSLManager::OnMixedContentRequest(this, request, ui_loop_); | 840 SSLManager::OnMixedContentRequest(this, request, ui_loop_); |
789 return; | 841 return; |
790 } | 842 } |
791 request->Start(); | 843 request->Start(); |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1208 bool enough_new_progress = (amt_since_last > (size / kHalfPercentIncrements)); | 1260 bool enough_new_progress = (amt_since_last > (size / kHalfPercentIncrements)); |
1209 bool too_much_time_passed = time_since_last > kOneSecond; | 1261 bool too_much_time_passed = time_since_last > kOneSecond; |
1210 | 1262 |
1211 if (is_finished || enough_new_progress || too_much_time_passed) { | 1263 if (is_finished || enough_new_progress || too_much_time_passed) { |
1212 info->resource_handler->OnUploadProgress(info->request_id, position, size); | 1264 info->resource_handler->OnUploadProgress(info->request_id, position, size); |
1213 info->waiting_for_upload_progress_ack = true; | 1265 info->waiting_for_upload_progress_ack = true; |
1214 info->last_upload_ticks = TimeTicks::Now(); | 1266 info->last_upload_ticks = TimeTicks::Now(); |
1215 info->last_upload_position = position; | 1267 info->last_upload_position = position; |
1216 } | 1268 } |
1217 } | 1269 } |
| 1270 |
| 1271 void ResourceDispatcherHost::BlockRequestsForRenderView( |
| 1272 int render_process_host_id, |
| 1273 int render_view_id) { |
| 1274 std::pair<int, int> key(render_process_host_id, render_view_id); |
| 1275 DCHECK(blocked_requests_map_.find(key) == blocked_requests_map_.end()) << |
| 1276 "BlockRequestsForRenderView called multiple time for the same RVH"; |
| 1277 blocked_requests_map_[key] = new BlockedRequestsList(); |
| 1278 } |
| 1279 |
| 1280 void ResourceDispatcherHost::ResumeBlockedRequestsForRenderView( |
| 1281 int render_process_host_id, |
| 1282 int render_view_id) { |
| 1283 ProcessBlockedRequestsForRenderView(render_process_host_id, |
| 1284 render_view_id, false); |
| 1285 } |
| 1286 |
| 1287 void ResourceDispatcherHost::CancelBlockedRequestsForRenderView( |
| 1288 int render_process_host_id, |
| 1289 int render_view_id) { |
| 1290 ProcessBlockedRequestsForRenderView(render_process_host_id, |
| 1291 render_view_id, true); |
| 1292 } |
| 1293 |
| 1294 void ResourceDispatcherHost::ProcessBlockedRequestsForRenderView( |
| 1295 int render_process_host_id, |
| 1296 int render_view_id, |
| 1297 bool cancel_requests) { |
| 1298 BlockedRequestMap::iterator iter = |
| 1299 blocked_requests_map_.find(std::pair<int, int>(render_process_host_id, |
| 1300 render_view_id)); |
| 1301 if (iter == blocked_requests_map_.end()) { |
| 1302 NOTREACHED(); |
| 1303 return; |
| 1304 } |
| 1305 |
| 1306 BlockedRequestsList* requests = iter->second; |
| 1307 |
| 1308 // Removing the vector from the map unblocks any subsequent requests. |
| 1309 blocked_requests_map_.erase(iter); |
| 1310 |
| 1311 for (BlockedRequestsList::iterator req_iter = requests->begin(); |
| 1312 req_iter != requests->end(); ++req_iter) { |
| 1313 if (cancel_requests) |
| 1314 delete req_iter->url_request; |
| 1315 else |
| 1316 BeginRequestInternal(req_iter->url_request, req_iter->mixed_content); |
| 1317 } |
| 1318 |
| 1319 delete requests; |
| 1320 } |
OLD | NEW |