| 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 |