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

Side by Side Diff: chrome/browser/renderer_host/resource_dispatcher_host.cc

Issue 159255: Fix a race condition where rapid back/forward clicks could close a tab... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "chrome/browser/renderer_host/resource_dispatcher_host.h" 7 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
8 8
9 #include <vector> 9 #include <vector>
10 10
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 102
103 // Maximum number of pending data messages sent to the renderer at any 103 // Maximum number of pending data messages sent to the renderer at any
104 // given time for a given request. 104 // given time for a given request.
105 const int kMaxPendingDataMessages = 20; 105 const int kMaxPendingDataMessages = 20;
106 106
107 // Maximum byte "cost" of all the outstanding requests for a renderer. 107 // Maximum byte "cost" of all the outstanding requests for a renderer.
108 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. 108 // See delcaration of |max_outstanding_requests_cost_per_process_| for details.
109 // This bound is 25MB, which allows for around 6000 outstanding requests. 109 // This bound is 25MB, which allows for around 6000 outstanding requests.
110 const int kMaxOutstandingRequestsCostPerProcess = 26214400; 110 const int kMaxOutstandingRequestsCostPerProcess = 26214400;
111 111
112 // A NotificationTask proxies a resource dispatcher notification from the IO 112 // Calls ClosePageIgnoringUnloadEvents on the UI thread for the given
113 // thread to the RenderViewHostDelegate on the UI thread. It should be 113 // RenderView.
114 // constructed on the IO thread and run in the UI thread. 114 //
115 class NotificationTask : public Task { 115 // If there are more functions we need to call on RVH, we should generalize this
116 // like the "Delegate" notification task below.
117 class RVHCloseNotificationTask : public Task {
118 public:
119 RVHCloseNotificationTask(int render_process_host_id,
120 int render_view_host_id)
121 : render_process_host_id_(render_process_host_id),
122 render_view_host_id_(render_view_host_id) {
123 }
124
125 virtual void Run() {
126 RenderViewHost* rvh = RenderViewHost::FromID(render_process_host_id_,
127 render_view_host_id_);
128 if (rvh)
129 rvh->ClosePageIgnoringUnloadEvents();
130 }
131
132 private:
133 int render_process_host_id_;
134 int render_view_host_id_;
135
136 DISALLOW_COPY_AND_ASSIGN(RVHCloseNotificationTask);
137 };
138
139 // A RVHDelegateNotificationTask proxies a resource dispatcher notification
140 // from the IO thread to the RenderViewHostDelegate on the UI thread. It should
141 // be constructed on the IO thread and run in the UI thread.
142 class RVHDelegateNotificationTask : public Task {
116 public: 143 public:
117 typedef void (RenderViewHostDelegate::Resource::* ResourceFunction) 144 typedef void (RenderViewHostDelegate::Resource::* ResourceFunction)
118 (ResourceRequestDetails*); 145 (ResourceRequestDetails*);
119 146
120 // Supply the originating URLRequest, a function on RenderViewHostDelegate 147 // Supply the originating URLRequest, a function on RenderViewHostDelegate
121 // to call, and the details to use as the parameter to the given function. 148 // to call, and the details to use as the parameter to the given function.
122 // 149 //
123 // This object will take ownership of the details pointer, which must be 150 // This object will take ownership of the details pointer, which must be
124 // allocated on the heap. 151 // allocated on the heap.
125 NotificationTask( 152 RVHDelegateNotificationTask(
126 URLRequest* request, 153 URLRequest* request,
127 ResourceFunction function, 154 ResourceFunction function,
128 ResourceRequestDetails* details) 155 ResourceRequestDetails* details)
129 : function_(function), 156 : render_process_host_id_(-1),
157 render_view_host_id_(-1),
158 function_(function),
130 details_(details) { 159 details_(details) {
131 if (!ResourceDispatcherHost::RenderViewForRequest(request, 160 if (!ResourceDispatcherHost::RenderViewForRequest(request,
132 &render_process_host_id_, 161 &render_process_host_id_,
133 &render_view_host_id_)) { 162 &render_view_host_id_)) {
134 NOTREACHED(); 163 NOTREACHED();
135 } 164 }
136 } 165 }
137 166
138 virtual void Run() { 167 virtual void Run() {
139 RenderViewHost* rvh = RenderViewHost::FromID(render_process_host_id_, 168 RenderViewHost* rvh = RenderViewHost::FromID(render_process_host_id_,
140 render_view_host_id_); 169 render_view_host_id_);
141 if (rvh) { 170 if (rvh) {
142 RenderViewHostDelegate::Resource* resource_delegate = 171 RenderViewHostDelegate::Resource* resource_delegate =
143 rvh->delegate()->GetResourceDelegate(); 172 rvh->delegate()->GetResourceDelegate();
144 if (resource_delegate) 173 if (resource_delegate)
145 (resource_delegate->*function_)(details_.get()); 174 (resource_delegate->*function_)(details_.get());
146 } 175 }
147 } 176 }
148 177
149 private: 178 private:
150 int render_process_host_id_; 179 int render_process_host_id_;
151 int render_view_host_id_; 180 int render_view_host_id_;
152 181
153 // The function to call on RenderViewHostDelegate::Resource on the UI thread. 182 // The function to call on RenderViewHostDelegate::Resource on the UI thread.
154 ResourceFunction function_; 183 ResourceFunction function_;
155 184
156 // The details for the notification. 185 // The details for the notification.
157 scoped_ptr<ResourceRequestDetails> details_; 186 scoped_ptr<ResourceRequestDetails> details_;
158 187
159 DISALLOW_COPY_AND_ASSIGN(NotificationTask); 188 DISALLOW_COPY_AND_ASSIGN(RVHDelegateNotificationTask);
160 }; 189 };
161 190
162 // Consults the RendererSecurity policy to determine whether the 191 // Consults the RendererSecurity policy to determine whether the
163 // ResourceDispatcherHost should service this request. A request might be 192 // ResourceDispatcherHost should service this request. A request might be
164 // disallowed if the renderer is not authorized to restrive the request URL or 193 // disallowed if the renderer is not authorized to restrive the request URL or
165 // if the renderer is attempting to upload an unauthorized file. 194 // if the renderer is attempting to upload an unauthorized file.
166 bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type, 195 bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type,
167 int process_id, 196 int process_id,
168 const ViewHostMsg_Resource_Request& request_data) { 197 const ViewHostMsg_Resource_Request& request_data) {
169 if (process_type == ChildProcessInfo::PLUGIN_PROCESS) 198 if (process_type == ChildProcessInfo::PLUGIN_PROCESS)
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 return; 547 return;
519 548
520 ExtraRequestInfo* info = ExtraInfoForRequest(i->second); 549 ExtraRequestInfo* info = ExtraInfoForRequest(i->second);
521 info->waiting_for_upload_progress_ack = false; 550 info->waiting_for_upload_progress_ack = false;
522 } 551 }
523 552
524 void ResourceDispatcherHost::OnCancelRequest(int request_id) { 553 void ResourceDispatcherHost::OnCancelRequest(int request_id) {
525 CancelRequest(receiver_->GetProcessId(), request_id, true, true); 554 CancelRequest(receiver_->GetProcessId(), request_id, true, true);
526 } 555 }
527 556
528 void ResourceDispatcherHost::OnClosePageACK(int new_render_process_host_id, 557 void ResourceDispatcherHost::OnClosePageACK(
529 int new_request_id) { 558 const ViewMsg_ClosePage_Params& params) {
530 GlobalRequestID global_id(new_render_process_host_id, new_request_id); 559 if (params.for_cross_site_transition) {
531 PendingRequestList::iterator i = pending_requests_.find(global_id); 560 // Closes for cross-site transitions are handled such that the cross-site
532 if (i == pending_requests_.end()) { 561 // transition continues.
533 // If there are no matching pending requests, then this is not a 562 GlobalRequestID global_id(params.new_render_process_host_id,
534 // cross-site navigation and we are just closing the tab/browser. 563 params.new_request_id);
535 ui_loop_->PostTask(FROM_HERE, NewRunnableFunction( 564 PendingRequestList::iterator i = pending_requests_.find(global_id);
536 &RenderViewHost::ClosePageIgnoringUnloadEvents, 565 if (i != pending_requests_.end()) {
537 new_render_process_host_id, 566 // The response we were meant to resume could have already been canceled.
538 new_request_id)); 567 ExtraRequestInfo* info = ExtraInfoForRequest(i->second);
539 return; 568 if (info->cross_site_handler)
540 } 569 info->cross_site_handler->ResumeResponse();
541 570 }
542 ExtraRequestInfo* info = ExtraInfoForRequest(i->second); 571 } else {
543 if (info->cross_site_handler) { 572 // This is a tab close, so just forward the message to close it.
544 info->cross_site_handler->ResumeResponse(); 573 DCHECK(params.new_render_process_host_id == -1);
574 DCHECK(params.new_request_id == -1);
575 ui_loop_->PostTask(
576 FROM_HERE,
577 new RVHCloseNotificationTask(params.closing_process_id,
578 params.closing_route_id));
545 } 579 }
546 } 580 }
547 581
548 // We are explicitly forcing the download of 'url'. 582 // We are explicitly forcing the download of 'url'.
549 void ResourceDispatcherHost::BeginDownload(const GURL& url, 583 void ResourceDispatcherHost::BeginDownload(const GURL& url,
550 const GURL& referrer, 584 const GURL& referrer,
551 int process_id, 585 int process_id,
552 int route_id, 586 int route_id,
553 URLRequestContext* request_context) { 587 URLRequestContext* request_context) {
554 if (is_shutdown_) 588 if (is_shutdown_)
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 (request->response_headers()->response_code() <= 599))); 1430 (request->response_headers()->response_code() <= 599)));
1397 return 0; 1431 return 0;
1398 } 1432 }
1399 1433
1400 void ResourceDispatcherHost::NotifyResponseStarted(URLRequest* request, 1434 void ResourceDispatcherHost::NotifyResponseStarted(URLRequest* request,
1401 int process_id) { 1435 int process_id) {
1402 // Notify the observers on the IO thread. 1436 // Notify the observers on the IO thread.
1403 FOR_EACH_OBSERVER(Observer, observer_list_, OnRequestStarted(this, request)); 1437 FOR_EACH_OBSERVER(Observer, observer_list_, OnRequestStarted(this, request));
1404 1438
1405 // Notify the observers on the UI thread. 1439 // Notify the observers on the UI thread.
1406 ui_loop_->PostTask(FROM_HERE, new NotificationTask(request, 1440 ui_loop_->PostTask(FROM_HERE, new RVHDelegateNotificationTask(request,
1407 &RenderViewHostDelegate::Resource::DidStartReceivingResourceResponse, 1441 &RenderViewHostDelegate::Resource::DidStartReceivingResourceResponse,
1408 new ResourceRequestDetails(request, 1442 new ResourceRequestDetails(request,
1409 GetCertID(request, process_id)))); 1443 GetCertID(request, process_id))));
1410 } 1444 }
1411 1445
1412 void ResourceDispatcherHost::NotifyResponseCompleted( 1446 void ResourceDispatcherHost::NotifyResponseCompleted(
1413 URLRequest* request, 1447 URLRequest* request,
1414 int process_id) { 1448 int process_id) {
1415 // Notify the observers on the IO thread. 1449 // Notify the observers on the IO thread.
1416 FOR_EACH_OBSERVER(Observer, observer_list_, 1450 FOR_EACH_OBSERVER(Observer, observer_list_,
1417 OnResponseCompleted(this, request)); 1451 OnResponseCompleted(this, request));
1418 } 1452 }
1419 1453
1420 void ResourceDispatcherHost::NotifyReceivedRedirect(URLRequest* request, 1454 void ResourceDispatcherHost::NotifyReceivedRedirect(URLRequest* request,
1421 int process_id, 1455 int process_id,
1422 const GURL& new_url) { 1456 const GURL& new_url) {
1423 // Notify the observers on the IO thread. 1457 // Notify the observers on the IO thread.
1424 FOR_EACH_OBSERVER(Observer, observer_list_, 1458 FOR_EACH_OBSERVER(Observer, observer_list_,
1425 OnReceivedRedirect(this, request, new_url)); 1459 OnReceivedRedirect(this, request, new_url));
1426 1460
1427 int cert_id = GetCertID(request, process_id); 1461 int cert_id = GetCertID(request, process_id);
1428 1462
1429 // Notify the observers on the UI thread. 1463 // Notify the observers on the UI thread.
1430 ui_loop_->PostTask(FROM_HERE, 1464 ui_loop_->PostTask(FROM_HERE,
1431 new NotificationTask(request, 1465 new RVHDelegateNotificationTask(request,
1432 &RenderViewHostDelegate::Resource::DidRedirectResource, 1466 &RenderViewHostDelegate::Resource::DidRedirectResource,
1433 new ResourceRedirectDetails(request, cert_id, new_url))); 1467 new ResourceRedirectDetails(request, cert_id, new_url)));
1434 } 1468 }
1435 1469
1436 namespace { 1470 namespace {
1437 1471
1438 // This function attempts to return the "more interesting" load state of |a| 1472 // This function attempts to return the "more interesting" load state of |a|
1439 // and |b|. We don't have temporal information about these load states 1473 // and |b|. We don't have temporal information about these load states
1440 // (meaning we don't know when we transitioned into these states), so we just 1474 // (meaning we don't know when we transitioned into these states), so we just
1441 // rank them according to how "interesting" the states are. 1475 // rank them according to how "interesting" the states are.
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 case ViewHostMsg_UploadProgress_ACK::ID: 1654 case ViewHostMsg_UploadProgress_ACK::ID:
1621 case ViewHostMsg_SyncLoad::ID: 1655 case ViewHostMsg_SyncLoad::ID:
1622 return true; 1656 return true;
1623 1657
1624 default: 1658 default:
1625 break; 1659 break;
1626 } 1660 }
1627 1661
1628 return false; 1662 return false;
1629 } 1663 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/resource_dispatcher_host.h ('k') | chrome/browser/tab_contents/render_view_host_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698