OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/child/resource_dispatcher.h" | 7 #include "content/child/resource_dispatcher.h" |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/debug/alias.h" | 12 #include "base/debug/alias.h" |
13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
14 #include "base/memory/shared_memory.h" | 14 #include "base/memory/shared_memory.h" |
15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
18 #include "content/child/request_extra_data.h" | 18 #include "content/child/request_extra_data.h" |
19 #include "content/child/site_isolation_policy.h" | 19 #include "content/child/site_isolation_policy.h" |
| 20 #include "content/child/webthreadedresourceprovider_impl.h" |
20 #include "content/common/inter_process_time_ticks_converter.h" | 21 #include "content/common/inter_process_time_ticks_converter.h" |
21 #include "content/common/resource_messages.h" | 22 #include "content/common/resource_messages.h" |
22 #include "content/public/child/resource_dispatcher_delegate.h" | 23 #include "content/public/child/resource_dispatcher_delegate.h" |
23 #include "content/public/common/resource_response.h" | 24 #include "content/public/common/resource_response.h" |
24 #include "net/base/net_errors.h" | 25 #include "net/base/net_errors.h" |
25 #include "net/base/net_util.h" | 26 #include "net/base/net_util.h" |
26 #include "net/base/request_priority.h" | 27 #include "net/base/request_priority.h" |
27 #include "net/http/http_response_headers.h" | 28 #include "net/http/http_response_headers.h" |
28 #include "webkit/common/resource_type.h" | 29 #include "webkit/common/resource_type.h" |
29 | 30 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 IPCResourceLoaderBridge(ResourceDispatcher* dispatcher, | 72 IPCResourceLoaderBridge(ResourceDispatcher* dispatcher, |
72 const ResourceLoaderBridge::RequestInfo& request_info); | 73 const ResourceLoaderBridge::RequestInfo& request_info); |
73 virtual ~IPCResourceLoaderBridge(); | 74 virtual ~IPCResourceLoaderBridge(); |
74 | 75 |
75 // ResourceLoaderBridge | 76 // ResourceLoaderBridge |
76 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; | 77 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; |
77 virtual bool Start(Peer* peer) OVERRIDE; | 78 virtual bool Start(Peer* peer) OVERRIDE; |
78 virtual void Cancel() OVERRIDE; | 79 virtual void Cancel() OVERRIDE; |
79 virtual void SetDefersLoading(bool value) OVERRIDE; | 80 virtual void SetDefersLoading(bool value) OVERRIDE; |
80 virtual void DidChangePriority(net::RequestPriority new_priority) OVERRIDE; | 81 virtual void DidChangePriority(net::RequestPriority new_priority) OVERRIDE; |
| 82 virtual blink::WebThreadedResourceProvider* |
| 83 CreateThreadedResourceProvider() OVERRIDE; |
81 virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE; | 84 virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE; |
82 | 85 |
83 private: | 86 private: |
84 ResourceLoaderBridge::Peer* peer_; | 87 ResourceLoaderBridge::Peer* peer_; |
85 | 88 |
86 // The resource dispatcher for this loader. The bridge doesn't own it, but | 89 // The resource dispatcher for this loader. The bridge doesn't own it, but |
87 // it's guaranteed to outlive the bridge. | 90 // it's guaranteed to outlive the bridge. |
88 ResourceDispatcher* dispatcher_; | 91 ResourceDispatcher* dispatcher_; |
89 | 92 |
90 // The request to send, created on initialization for modification and | 93 // The request to send, created on initialization for modification and |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 void IPCResourceLoaderBridge::DidChangePriority( | 229 void IPCResourceLoaderBridge::DidChangePriority( |
227 net::RequestPriority new_priority) { | 230 net::RequestPriority new_priority) { |
228 if (request_id_ < 0) { | 231 if (request_id_ < 0) { |
229 NOTREACHED() << "Trying to change priority of an unstarted request"; | 232 NOTREACHED() << "Trying to change priority of an unstarted request"; |
230 return; | 233 return; |
231 } | 234 } |
232 | 235 |
233 dispatcher_->DidChangePriority(routing_id_, request_id_, new_priority); | 236 dispatcher_->DidChangePriority(routing_id_, request_id_, new_priority); |
234 } | 237 } |
235 | 238 |
| 239 blink::WebThreadedResourceProvider* |
| 240 IPCResourceLoaderBridge::CreateThreadedResourceProvider() { |
| 241 if (request_id_ < 0) { |
| 242 NOTREACHED() << "Trying to set parser-resource bridge on unstarted request"; |
| 243 return NULL; |
| 244 } |
| 245 |
| 246 return dispatcher_->CreateThreadedResourceProvider(request_id_); |
| 247 } |
| 248 |
236 void IPCResourceLoaderBridge::SyncLoad(SyncLoadResponse* response) { | 249 void IPCResourceLoaderBridge::SyncLoad(SyncLoadResponse* response) { |
237 if (request_id_ != -1) { | 250 if (request_id_ != -1) { |
238 NOTREACHED() << "Starting a request twice"; | 251 NOTREACHED() << "Starting a request twice"; |
239 response->error_code = net::ERR_FAILED; | 252 response->error_code = net::ERR_FAILED; |
240 return; | 253 return; |
241 } | 254 } |
242 | 255 |
243 request_id_ = MakeRequestID(); | 256 request_id_ = MakeRequestID(); |
244 is_synchronous_request_ = true; | 257 is_synchronous_request_ = true; |
245 | 258 |
(...skipping 23 matching lines...) Expand all Loading... |
269 // ResourceDispatcher --------------------------------------------------------- | 282 // ResourceDispatcher --------------------------------------------------------- |
270 | 283 |
271 ResourceDispatcher::ResourceDispatcher(IPC::Sender* sender) | 284 ResourceDispatcher::ResourceDispatcher(IPC::Sender* sender) |
272 : message_sender_(sender), | 285 : message_sender_(sender), |
273 weak_factory_(this), | 286 weak_factory_(this), |
274 delegate_(NULL), | 287 delegate_(NULL), |
275 io_timestamp_(base::TimeTicks()) { | 288 io_timestamp_(base::TimeTicks()) { |
276 } | 289 } |
277 | 290 |
278 ResourceDispatcher::~ResourceDispatcher() { | 291 ResourceDispatcher::~ResourceDispatcher() { |
| 292 WebThreadedResourceProviderImpl::Cleanup(); |
279 } | 293 } |
280 | 294 |
281 // ResourceDispatcher implementation ------------------------------------------ | 295 // ResourceDispatcher implementation ------------------------------------------ |
282 | 296 |
283 bool ResourceDispatcher::OnMessageReceived(const IPC::Message& message) { | 297 bool ResourceDispatcher::OnMessageReceived(const IPC::Message& message) { |
284 if (!IsResourceDispatcherMessage(message)) { | 298 if (!IsResourceDispatcherMessage(message)) { |
285 return false; | 299 return false; |
286 } | 300 } |
287 | 301 |
288 int request_id; | 302 int request_id; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 request_info->peer->OnReceivedData(alternative_data.data(), | 464 request_info->peer->OnReceivedData(alternative_data.data(), |
451 alternative_data.size(), | 465 alternative_data.size(), |
452 alternative_data.size()); | 466 alternative_data.size()); |
453 } | 467 } |
454 | 468 |
455 UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime", | 469 UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime", |
456 base::TimeTicks::Now() - time_start); | 470 base::TimeTicks::Now() - time_start); |
457 } | 471 } |
458 | 472 |
459 // Acknowledge the reception of this data. | 473 // Acknowledge the reception of this data. |
460 message_sender()->Send(new ResourceHostMsg_DataReceived_ACK(request_id)); | 474 if (!request_info || request_info->send_data_acks) |
| 475 SendDataACK(request_id); |
461 } | 476 } |
462 | 477 |
463 void ResourceDispatcher::OnDownloadedData(int request_id, | 478 void ResourceDispatcher::OnDownloadedData(int request_id, |
464 int data_len, | 479 int data_len, |
465 int encoded_data_length) { | 480 int encoded_data_length) { |
466 // Acknowledge the reception of this message. | 481 // Acknowledge the reception of this message. |
467 message_sender()->Send( | 482 message_sender()->Send( |
468 new ResourceHostMsg_DataDownloaded_ACK(request_id)); | 483 new ResourceHostMsg_DataDownloaded_ACK(request_id)); |
469 | 484 |
470 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 485 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 if (it == pending_requests_.end()) { | 600 if (it == pending_requests_.end()) { |
586 DVLOG(1) << "unknown request"; | 601 DVLOG(1) << "unknown request"; |
587 return; | 602 return; |
588 } | 603 } |
589 | 604 |
590 // |request_id| will be removed from |pending_requests_| when | 605 // |request_id| will be removed from |pending_requests_| when |
591 // OnRequestComplete returns with ERR_ABORTED. | 606 // OnRequestComplete returns with ERR_ABORTED. |
592 message_sender()->Send(new ResourceHostMsg_CancelRequest(request_id)); | 607 message_sender()->Send(new ResourceHostMsg_CancelRequest(request_id)); |
593 } | 608 } |
594 | 609 |
| 610 void ResourceDispatcher::StopSendingDataACKs(int request_id) { |
| 611 PendingRequestList::iterator it = pending_requests_.find(request_id); |
| 612 if (it != pending_requests_.end()) |
| 613 it->second.send_data_acks = false; |
| 614 } |
| 615 |
| 616 void ResourceDispatcher::SendDataACK(int request_id) { |
| 617 message_sender()->Send(new ResourceHostMsg_DataReceived_ACK(request_id)); |
| 618 } |
| 619 |
595 void ResourceDispatcher::SetDefersLoading(int request_id, bool value) { | 620 void ResourceDispatcher::SetDefersLoading(int request_id, bool value) { |
596 PendingRequestList::iterator it = pending_requests_.find(request_id); | 621 PendingRequestList::iterator it = pending_requests_.find(request_id); |
597 if (it == pending_requests_.end()) { | 622 if (it == pending_requests_.end()) { |
598 DLOG(ERROR) << "unknown request"; | 623 DLOG(ERROR) << "unknown request"; |
599 return; | 624 return; |
600 } | 625 } |
601 PendingRequestInfo& request_info = it->second; | 626 PendingRequestInfo& request_info = it->second; |
602 if (value) { | 627 if (value) { |
603 request_info.is_deferred = value; | 628 request_info.is_deferred = value; |
604 } else if (request_info.is_deferred) { | 629 } else if (request_info.is_deferred) { |
605 request_info.is_deferred = false; | 630 request_info.is_deferred = false; |
606 | 631 |
607 FollowPendingRedirect(request_id, request_info); | 632 FollowPendingRedirect(request_id, request_info); |
608 | 633 |
609 base::MessageLoop::current()->PostTask( | 634 base::MessageLoop::current()->PostTask( |
610 FROM_HERE, | 635 FROM_HERE, |
611 base::Bind(&ResourceDispatcher::FlushDeferredMessages, | 636 base::Bind(&ResourceDispatcher::FlushDeferredMessages, |
612 weak_factory_.GetWeakPtr(), | 637 weak_factory_.GetWeakPtr(), |
613 request_id)); | 638 request_id)); |
614 } | 639 } |
615 } | 640 } |
616 | 641 |
617 void ResourceDispatcher::DidChangePriority( | 642 void ResourceDispatcher::DidChangePriority( |
618 int routing_id, int request_id, net::RequestPriority new_priority) { | 643 int routing_id, int request_id, net::RequestPriority new_priority) { |
619 DCHECK(ContainsKey(pending_requests_, request_id)); | 644 DCHECK(ContainsKey(pending_requests_, request_id)); |
620 message_sender()->Send(new ResourceHostMsg_DidChangePriority( | 645 message_sender()->Send(new ResourceHostMsg_DidChangePriority( |
621 request_id, new_priority)); | 646 request_id, new_priority)); |
622 } | 647 } |
623 | 648 |
| 649 blink::WebThreadedResourceProvider* |
| 650 ResourceDispatcher::CreateThreadedResourceProvider(int request_id) { |
| 651 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
| 652 |
| 653 return new WebThreadedResourceProviderImpl(request_id, |
| 654 weak_factory_.GetWeakPtr(), |
| 655 request_info->buffer, |
| 656 request_info->buffer_size); |
| 657 } |
| 658 |
624 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() | 659 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() |
625 : peer(NULL), | 660 : peer(NULL), |
626 resource_type(ResourceType::SUB_RESOURCE), | 661 resource_type(ResourceType::SUB_RESOURCE), |
627 is_deferred(false), | 662 is_deferred(false), |
628 buffer_size(0) { | 663 buffer_size(0), |
| 664 send_data_acks(true) { |
629 } | 665 } |
630 | 666 |
631 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( | 667 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( |
632 webkit_glue::ResourceLoaderBridge::Peer* peer, | 668 webkit_glue::ResourceLoaderBridge::Peer* peer, |
633 ResourceType::Type resource_type, | 669 ResourceType::Type resource_type, |
634 int origin_pid, | 670 int origin_pid, |
635 const GURL& frame_origin, | 671 const GURL& frame_origin, |
636 const GURL& request_url) | 672 const GURL& request_url) |
637 : peer(peer), | 673 : peer(peer), |
638 resource_type(resource_type), | 674 resource_type(resource_type), |
639 origin_pid(origin_pid), | 675 origin_pid(origin_pid), |
640 is_deferred(false), | 676 is_deferred(false), |
641 url(request_url), | 677 url(request_url), |
642 frame_origin(frame_origin), | 678 frame_origin(frame_origin), |
643 response_url(request_url), | 679 response_url(request_url), |
644 request_start(base::TimeTicks::Now()) { | 680 request_start(base::TimeTicks::Now()), |
| 681 send_data_acks(true) { |
645 } | 682 } |
646 | 683 |
647 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} | 684 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} |
648 | 685 |
649 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { | 686 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { |
650 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message) | 687 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message) |
651 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress) | 688 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress) |
652 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse) | 689 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse) |
653 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, | 690 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, |
654 OnReceivedCachedMetadata) | 691 OnReceivedCachedMetadata) |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { | 839 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { |
803 while (!queue->empty()) { | 840 while (!queue->empty()) { |
804 IPC::Message* message = queue->front(); | 841 IPC::Message* message = queue->front(); |
805 ReleaseResourcesInDataMessage(*message); | 842 ReleaseResourcesInDataMessage(*message); |
806 queue->pop_front(); | 843 queue->pop_front(); |
807 delete message; | 844 delete message; |
808 } | 845 } |
809 } | 846 } |
810 | 847 |
811 } // namespace content | 848 } // namespace content |
OLD | NEW |