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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 return true; | 286 return true; |
287 } | 287 } |
288 | 288 |
289 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 289 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
290 if (!request_info) { | 290 if (!request_info) { |
291 // Release resources in the message if it is a data message. | 291 // Release resources in the message if it is a data message. |
292 ReleaseResourcesInDataMessage(message); | 292 ReleaseResourcesInDataMessage(message); |
293 return true; | 293 return true; |
294 } | 294 } |
295 | 295 |
296 // If the request has been canceled, only dispatch | |
297 // ResourceMsg_RequestComplete (otherwise resource leaks) and drop other | |
298 // messages. | |
299 if (request_info->is_canceled) { | |
300 if (message.type() == ResourceMsg_RequestComplete::ID) { | |
301 DispatchMessage(message); | |
302 } else { | |
303 ReleaseResourcesInDataMessage(message); | |
304 } | |
305 return true; | |
306 } | |
307 | |
308 if (request_info->is_deferred) { | 296 if (request_info->is_deferred) { |
309 request_info->deferred_message_queue.push_back(new IPC::Message(message)); | 297 request_info->deferred_message_queue.push_back(new IPC::Message(message)); |
310 return true; | 298 return true; |
311 } | 299 } |
312 // Make sure any deferred messages are dispatched before we dispatch more. | 300 // Make sure any deferred messages are dispatched before we dispatch more. |
313 if (!request_info->deferred_message_queue.empty()) { | 301 if (!request_info->deferred_message_queue.empty()) { |
314 FlushDeferredMessages(request_id); | 302 FlushDeferredMessages(request_id); |
315 // The request could have been deferred now. If yes then the current | 303 // The request could have been deferred now. If yes then the current |
316 // message has to be queued up. The request_info instance should remain | 304 // message has to be queued up. The request_info instance should remain |
317 // valid here as there are pending messages for it. | 305 // valid here as there are pending messages for it. |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 return true; | 586 return true; |
599 } | 587 } |
600 | 588 |
601 void ResourceDispatcher::CancelPendingRequest(int request_id) { | 589 void ResourceDispatcher::CancelPendingRequest(int request_id) { |
602 PendingRequestList::iterator it = pending_requests_.find(request_id); | 590 PendingRequestList::iterator it = pending_requests_.find(request_id); |
603 if (it == pending_requests_.end()) { | 591 if (it == pending_requests_.end()) { |
604 DVLOG(1) << "unknown request"; | 592 DVLOG(1) << "unknown request"; |
605 return; | 593 return; |
606 } | 594 } |
607 | 595 |
608 PendingRequestInfo& request_info = it->second; | |
609 request_info.is_canceled = true; | |
610 | |
611 // Because message handlers could result in request_info being destroyed, | |
612 // we need to work with a stack reference to the deferred queue. | |
613 MessageQueue queue; | |
614 queue.swap(request_info.deferred_message_queue); | |
615 // Removes pending requests. If ResourceMsg_RequestComplete was queued, | |
616 // dispatch it. | |
617 bool first_message = true; | |
618 while (!queue.empty()) { | |
619 IPC::Message* message = queue.front(); | |
620 if (message->type() == ResourceMsg_RequestComplete::ID) { | |
621 if (first_message) { | |
622 // Dispatch as-is. | |
623 DispatchMessage(*message); | |
624 } else { | |
625 // If we skip some ResourceMsg_DataReceived and then dispatched the | |
626 // original ResourceMsg_RequestComplete(status=success), chrome will | |
627 // crash because it entered an unexpected state. So replace | |
628 // ResourceMsg_RequestComplete with failure status. | |
629 ResourceMsg_RequestCompleteData request_complete_data; | |
630 request_complete_data.error_code = net::ERR_ABORTED; | |
631 request_complete_data.was_ignored_by_handler = false; | |
632 request_complete_data.exists_in_cache = false; | |
633 request_complete_data.completion_time = base::TimeTicks(); | |
634 request_complete_data.encoded_data_length = 0; | |
635 | |
636 ResourceMsg_RequestComplete error_message(request_id, | |
637 request_complete_data); | |
638 DispatchMessage(error_message); | |
639 } | |
640 } else { | |
641 ReleaseResourcesInDataMessage(*message); | |
642 } | |
643 first_message = false; | |
644 queue.pop_front(); | |
645 delete message; | |
646 } | |
647 | |
648 // |request_id| will be removed from |pending_requests_| when | 596 // |request_id| will be removed from |pending_requests_| when |
649 // OnRequestComplete returns with ERR_ABORTED. | 597 // OnRequestComplete returns with ERR_ABORTED. |
650 message_sender()->Send(new ResourceHostMsg_CancelRequest(request_id)); | 598 message_sender()->Send(new ResourceHostMsg_CancelRequest(request_id)); |
651 } | 599 } |
652 | 600 |
653 void ResourceDispatcher::SetDefersLoading(int request_id, bool value) { | 601 void ResourceDispatcher::SetDefersLoading(int request_id, bool value) { |
654 PendingRequestList::iterator it = pending_requests_.find(request_id); | 602 PendingRequestList::iterator it = pending_requests_.find(request_id); |
655 if (it == pending_requests_.end()) { | 603 if (it == pending_requests_.end()) { |
656 DLOG(ERROR) << "unknown request"; | 604 DLOG(ERROR) << "unknown request"; |
657 return; | 605 return; |
(...skipping 19 matching lines...) Expand all Loading... |
677 int intra_priority_value) { | 625 int intra_priority_value) { |
678 DCHECK(ContainsKey(pending_requests_, request_id)); | 626 DCHECK(ContainsKey(pending_requests_, request_id)); |
679 message_sender()->Send(new ResourceHostMsg_DidChangePriority( | 627 message_sender()->Send(new ResourceHostMsg_DidChangePriority( |
680 request_id, new_priority, intra_priority_value)); | 628 request_id, new_priority, intra_priority_value)); |
681 } | 629 } |
682 | 630 |
683 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() | 631 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() |
684 : peer(NULL), | 632 : peer(NULL), |
685 resource_type(ResourceType::SUB_RESOURCE), | 633 resource_type(ResourceType::SUB_RESOURCE), |
686 is_deferred(false), | 634 is_deferred(false), |
687 is_canceled(false), | |
688 download_to_file(false), | 635 download_to_file(false), |
689 blocked_response(false), | 636 blocked_response(false), |
690 buffer_size(0) { | 637 buffer_size(0) { |
691 } | 638 } |
692 | 639 |
693 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( | 640 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( |
694 RequestPeer* peer, | 641 RequestPeer* peer, |
695 ResourceType::Type resource_type, | 642 ResourceType::Type resource_type, |
696 int origin_pid, | 643 int origin_pid, |
697 const GURL& frame_origin, | 644 const GURL& frame_origin, |
698 const GURL& request_url, | 645 const GURL& request_url, |
699 bool download_to_file) | 646 bool download_to_file) |
700 : peer(peer), | 647 : peer(peer), |
701 resource_type(resource_type), | 648 resource_type(resource_type), |
702 origin_pid(origin_pid), | 649 origin_pid(origin_pid), |
703 is_deferred(false), | 650 is_deferred(false), |
704 is_canceled(false), | |
705 url(request_url), | 651 url(request_url), |
706 frame_origin(frame_origin), | 652 frame_origin(frame_origin), |
707 response_url(request_url), | 653 response_url(request_url), |
708 download_to_file(download_to_file), | 654 download_to_file(download_to_file), |
709 request_start(base::TimeTicks::Now()), | 655 request_start(base::TimeTicks::Now()), |
710 blocked_response(false) {} | 656 blocked_response(false) {} |
711 | 657 |
712 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} | 658 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} |
713 | 659 |
714 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { | 660 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
867 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { | 813 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { |
868 while (!queue->empty()) { | 814 while (!queue->empty()) { |
869 IPC::Message* message = queue->front(); | 815 IPC::Message* message = queue->front(); |
870 ReleaseResourcesInDataMessage(*message); | 816 ReleaseResourcesInDataMessage(*message); |
871 queue->pop_front(); | 817 queue->pop_front(); |
872 delete message; | 818 delete message; |
873 } | 819 } |
874 } | 820 } |
875 | 821 |
876 } // namespace content | 822 } // namespace content |
OLD | NEW |