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" |
(...skipping 29 matching lines...) Expand all Loading... |
40 | 40 |
41 // Converts |time| from a remote to local TimeTicks, overwriting the original | 41 // Converts |time| from a remote to local TimeTicks, overwriting the original |
42 // value. | 42 // value. |
43 void RemoteToLocalTimeTicks( | 43 void RemoteToLocalTimeTicks( |
44 const InterProcessTimeTicksConverter& converter, | 44 const InterProcessTimeTicksConverter& converter, |
45 base::TimeTicks* time) { | 45 base::TimeTicks* time) { |
46 RemoteTimeTicks remote_time = RemoteTimeTicks::FromTimeTicks(*time); | 46 RemoteTimeTicks remote_time = RemoteTimeTicks::FromTimeTicks(*time); |
47 *time = converter.ToLocalTimeTicks(remote_time).ToTimeTicks(); | 47 *time = converter.ToLocalTimeTicks(remote_time).ToTimeTicks(); |
48 } | 48 } |
49 | 49 |
50 | 50 void CrashOnMapFailure() { |
51 } // namespace | |
52 | |
53 static void CrashOnMapFailure() { | |
54 #if defined(OS_WIN) | 51 #if defined(OS_WIN) |
55 DWORD last_err = GetLastError(); | 52 DWORD last_err = GetLastError(); |
56 base::debug::Alias(&last_err); | 53 base::debug::Alias(&last_err); |
57 #endif | 54 #endif |
58 CHECK(false); | 55 CHECK(false); |
59 } | 56 } |
60 | 57 |
61 // Each resource request is assigned an ID scoped to this process. | 58 // Each resource request is assigned an ID scoped to this process. |
62 static int MakeRequestID() { | 59 int MakeRequestID() { |
63 // NOTE: The resource_dispatcher_host also needs probably unique | 60 // NOTE: The resource_dispatcher_host also needs probably unique |
64 // request_ids, so they count down from -2 (-1 is a special we're | 61 // request_ids, so they count down from -2 (-1 is a special we're |
65 // screwed value), while the renderer process counts up. | 62 // screwed value), while the renderer process counts up. |
66 static int next_request_id = 0; | 63 static int next_request_id = 0; |
67 return next_request_id++; | 64 return next_request_id++; |
68 } | 65 } |
69 | 66 |
| 67 } // namespace |
| 68 |
70 // ResourceLoaderBridge implementation ---------------------------------------- | 69 // ResourceLoaderBridge implementation ---------------------------------------- |
71 | 70 |
72 class IPCResourceLoaderBridge : public ResourceLoaderBridge { | 71 class IPCResourceLoaderBridge : public ResourceLoaderBridge { |
73 public: | 72 public: |
74 IPCResourceLoaderBridge(ResourceDispatcher* dispatcher, | 73 IPCResourceLoaderBridge(ResourceDispatcher* dispatcher, |
75 const RequestInfo& request_info); | 74 const RequestInfo& request_info); |
76 virtual ~IPCResourceLoaderBridge(); | 75 virtual ~IPCResourceLoaderBridge(); |
77 | 76 |
78 // ResourceLoaderBridge | 77 // ResourceLoaderBridge |
79 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; | 78 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 frame_origin_ = extra_data->frame_origin(); | 154 frame_origin_ = extra_data->frame_origin(); |
156 } | 155 } |
157 | 156 |
158 IPCResourceLoaderBridge::~IPCResourceLoaderBridge() { | 157 IPCResourceLoaderBridge::~IPCResourceLoaderBridge() { |
159 // we remove our hook for the resource dispatcher only when going away, since | 158 // we remove our hook for the resource dispatcher only when going away, since |
160 // it doesn't keep track of whether we've force terminated the request | 159 // it doesn't keep track of whether we've force terminated the request |
161 if (request_id_ >= 0) { | 160 if (request_id_ >= 0) { |
162 // this operation may fail, as the dispatcher will have preemptively | 161 // this operation may fail, as the dispatcher will have preemptively |
163 // removed us when the renderer sends the ReceivedAllData message. | 162 // removed us when the renderer sends the ReceivedAllData message. |
164 dispatcher_->RemovePendingRequest(request_id_); | 163 dispatcher_->RemovePendingRequest(request_id_); |
165 | |
166 if (request_.download_to_file) { | |
167 dispatcher_->message_sender()->Send( | |
168 new ResourceHostMsg_ReleaseDownloadedFile(request_id_)); | |
169 } | |
170 } | 164 } |
171 } | 165 } |
172 | 166 |
173 void IPCResourceLoaderBridge::SetRequestBody( | 167 void IPCResourceLoaderBridge::SetRequestBody( |
174 ResourceRequestBody* request_body) { | 168 ResourceRequestBody* request_body) { |
175 DCHECK(request_id_ == -1) << "request already started"; | 169 DCHECK(request_id_ == -1) << "request already started"; |
176 request_.request_body = request_body; | 170 request_.request_body = request_body; |
177 } | 171 } |
178 | 172 |
179 // Writes a footer on the message and sends it | 173 // Writes a footer on the message and sends it |
180 bool IPCResourceLoaderBridge::Start(RequestPeer* peer) { | 174 bool IPCResourceLoaderBridge::Start(RequestPeer* peer) { |
181 if (request_id_ != -1) { | 175 if (request_id_ != -1) { |
182 NOTREACHED() << "Starting a request twice"; | 176 NOTREACHED() << "Starting a request twice"; |
183 return false; | 177 return false; |
184 } | 178 } |
185 | 179 |
186 peer_ = peer; | 180 peer_ = peer; |
187 | 181 |
188 // generate the request ID, and append it to the message | 182 // generate the request ID, and append it to the message |
189 request_id_ = dispatcher_->AddPendingRequest(peer_, | 183 request_id_ = dispatcher_->AddPendingRequest(peer_, |
190 request_.resource_type, | 184 request_.resource_type, |
191 request_.origin_pid, | 185 request_.origin_pid, |
192 frame_origin_, | 186 frame_origin_, |
193 request_.url); | 187 request_.url, |
| 188 request_.download_to_file); |
194 | 189 |
195 return dispatcher_->message_sender()->Send( | 190 return dispatcher_->message_sender()->Send( |
196 new ResourceHostMsg_RequestResource(routing_id_, request_id_, request_)); | 191 new ResourceHostMsg_RequestResource(routing_id_, request_id_, request_)); |
197 } | 192 } |
198 | 193 |
199 void IPCResourceLoaderBridge::Cancel() { | 194 void IPCResourceLoaderBridge::Cancel() { |
200 if (request_id_ < 0) { | 195 if (request_id_ < 0) { |
201 NOTREACHED() << "Trying to cancel an unstarted request"; | 196 NOTREACHED() << "Trying to cancel an unstarted request"; |
202 return; | 197 return; |
203 } | 198 } |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 request_complete_data.exists_in_cache, | 561 request_complete_data.exists_in_cache, |
567 request_complete_data.security_info, | 562 request_complete_data.security_info, |
568 renderer_completion_time, | 563 renderer_completion_time, |
569 request_complete_data.encoded_data_length); | 564 request_complete_data.encoded_data_length); |
570 } | 565 } |
571 | 566 |
572 int ResourceDispatcher::AddPendingRequest(RequestPeer* callback, | 567 int ResourceDispatcher::AddPendingRequest(RequestPeer* callback, |
573 ResourceType::Type resource_type, | 568 ResourceType::Type resource_type, |
574 int origin_pid, | 569 int origin_pid, |
575 const GURL& frame_origin, | 570 const GURL& frame_origin, |
576 const GURL& request_url) { | 571 const GURL& request_url, |
| 572 bool download_to_file) { |
577 // Compute a unique request_id for this renderer process. | 573 // Compute a unique request_id for this renderer process. |
578 int id = MakeRequestID(); | 574 int id = MakeRequestID(); |
579 pending_requests_[id] = PendingRequestInfo( | 575 pending_requests_[id] = PendingRequestInfo(callback, |
580 callback, resource_type, origin_pid, frame_origin, request_url); | 576 resource_type, |
| 577 origin_pid, |
| 578 frame_origin, |
| 579 request_url, |
| 580 download_to_file); |
581 return id; | 581 return id; |
582 } | 582 } |
583 | 583 |
584 bool ResourceDispatcher::RemovePendingRequest(int request_id) { | 584 bool ResourceDispatcher::RemovePendingRequest(int request_id) { |
585 PendingRequestList::iterator it = pending_requests_.find(request_id); | 585 PendingRequestList::iterator it = pending_requests_.find(request_id); |
586 if (it == pending_requests_.end()) | 586 if (it == pending_requests_.end()) |
587 return false; | 587 return false; |
588 | 588 |
589 PendingRequestInfo& request_info = it->second; | 589 PendingRequestInfo& request_info = it->second; |
| 590 |
| 591 bool release_downloaded_file = request_info.download_to_file; |
| 592 |
590 ReleaseResourcesInMessageQueue(&request_info.deferred_message_queue); | 593 ReleaseResourcesInMessageQueue(&request_info.deferred_message_queue); |
591 pending_requests_.erase(it); | 594 pending_requests_.erase(it); |
592 | 595 |
| 596 if (release_downloaded_file) { |
| 597 message_sender_->Send( |
| 598 new ResourceHostMsg_ReleaseDownloadedFile(request_id)); |
| 599 } |
| 600 |
593 return true; | 601 return true; |
594 } | 602 } |
595 | 603 |
596 void ResourceDispatcher::CancelPendingRequest(int request_id) { | 604 void ResourceDispatcher::CancelPendingRequest(int request_id) { |
597 PendingRequestList::iterator it = pending_requests_.find(request_id); | 605 PendingRequestList::iterator it = pending_requests_.find(request_id); |
598 if (it == pending_requests_.end()) { | 606 if (it == pending_requests_.end()) { |
599 DVLOG(1) << "unknown request"; | 607 DVLOG(1) << "unknown request"; |
600 return; | 608 return; |
601 } | 609 } |
602 | 610 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 FollowPendingRedirect(request_id, request_info); | 668 FollowPendingRedirect(request_id, request_info); |
661 | 669 |
662 base::MessageLoop::current()->PostTask( | 670 base::MessageLoop::current()->PostTask( |
663 FROM_HERE, | 671 FROM_HERE, |
664 base::Bind(&ResourceDispatcher::FlushDeferredMessages, | 672 base::Bind(&ResourceDispatcher::FlushDeferredMessages, |
665 weak_factory_.GetWeakPtr(), | 673 weak_factory_.GetWeakPtr(), |
666 request_id)); | 674 request_id)); |
667 } | 675 } |
668 } | 676 } |
669 | 677 |
670 void ResourceDispatcher::DidChangePriority( | 678 void ResourceDispatcher::DidChangePriority(int routing_id, |
671 int routing_id, int request_id, net::RequestPriority new_priority, | 679 int request_id, |
672 int intra_priority_value) { | 680 net::RequestPriority new_priority, |
| 681 int intra_priority_value) { |
673 DCHECK(ContainsKey(pending_requests_, request_id)); | 682 DCHECK(ContainsKey(pending_requests_, request_id)); |
674 message_sender()->Send(new ResourceHostMsg_DidChangePriority( | 683 message_sender()->Send(new ResourceHostMsg_DidChangePriority( |
675 request_id, new_priority, intra_priority_value)); | 684 request_id, new_priority, intra_priority_value)); |
676 } | 685 } |
677 | 686 |
678 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() | 687 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() |
679 : peer(NULL), | 688 : peer(NULL), |
680 resource_type(ResourceType::SUB_RESOURCE), | 689 resource_type(ResourceType::SUB_RESOURCE), |
681 is_deferred(false), | 690 is_deferred(false), |
682 is_canceled(false), | 691 is_canceled(false), |
| 692 download_to_file(false), |
683 blocked_response(false), | 693 blocked_response(false), |
684 buffer_size(0) { | 694 buffer_size(0) { |
685 } | 695 } |
686 | 696 |
687 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( | 697 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( |
688 RequestPeer* peer, | 698 RequestPeer* peer, |
689 ResourceType::Type resource_type, | 699 ResourceType::Type resource_type, |
690 int origin_pid, | 700 int origin_pid, |
691 const GURL& frame_origin, | 701 const GURL& frame_origin, |
692 const GURL& request_url) | 702 const GURL& request_url, |
| 703 bool download_to_file) |
693 : peer(peer), | 704 : peer(peer), |
694 resource_type(resource_type), | 705 resource_type(resource_type), |
695 origin_pid(origin_pid), | 706 origin_pid(origin_pid), |
696 is_deferred(false), | 707 is_deferred(false), |
697 is_canceled(false), | 708 is_canceled(false), |
698 url(request_url), | 709 url(request_url), |
699 frame_origin(frame_origin), | 710 frame_origin(frame_origin), |
700 response_url(request_url), | 711 response_url(request_url), |
| 712 download_to_file(download_to_file), |
701 request_start(base::TimeTicks::Now()), | 713 request_start(base::TimeTicks::Now()), |
702 blocked_response(false) {} | 714 blocked_response(false) {} |
703 | 715 |
704 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} | 716 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} |
705 | 717 |
706 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { | 718 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { |
707 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message) | 719 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message) |
708 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress) | 720 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress) |
709 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse) | 721 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse) |
710 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, | 722 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { | 871 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { |
860 while (!queue->empty()) { | 872 while (!queue->empty()) { |
861 IPC::Message* message = queue->front(); | 873 IPC::Message* message = queue->front(); |
862 ReleaseResourcesInDataMessage(*message); | 874 ReleaseResourcesInDataMessage(*message); |
863 queue->pop_front(); | 875 queue->pop_front(); |
864 delete message; | 876 delete message; |
865 } | 877 } |
866 } | 878 } |
867 | 879 |
868 } // namespace content | 880 } // namespace content |
OLD | NEW |