 Chromium Code Reviews
 Chromium Code Reviews Issue 2425173003:
  Deal with canceled requests when flushing deferred messages.  (Closed)
    
  
    Issue 2425173003:
  Deal with canceled requests when flushing deferred messages.  (Closed) 
  | 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 <utility> | 9 #include <utility> | 
| 10 | 10 | 
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 return true; | 162 return true; | 
| 163 } | 163 } | 
| 164 | 164 | 
| 165 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 165 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 
| 166 if (!request_info) { | 166 if (!request_info) { | 
| 167 // Release resources in the message if it is a data message. | 167 // Release resources in the message if it is a data message. | 
| 168 ReleaseResourcesInDataMessage(message); | 168 ReleaseResourcesInDataMessage(message); | 
| 169 return true; | 169 return true; | 
| 170 } | 170 } | 
| 171 | 171 | 
| 172 if (request_info->is_deferred) { | 172 // Make sure any deferred messages are dispatched before we dispatch more. | 
| 173 if (request_info->is_deferred || | |
| 174 !request_info->deferred_message_queue.empty()) { | |
| 173 request_info->deferred_message_queue.push_back(new IPC::Message(message)); | 175 request_info->deferred_message_queue.push_back(new IPC::Message(message)); | 
| 176 // Dispatches the messages only if the request is no longer deferred. | |
| 
kinuko
2016/10/19 13:35:53
nit: to make it clearer that FlushDeferredMessages
 
jb
2016/10/20 13:06:50
Makes sense. I will add an extra if for clarity.
 | |
| 177 FlushDeferredMessages(request_id); | |
| 174 return true; | 178 return true; | 
| 175 } | 179 } | 
| 176 // Make sure any deferred messages are dispatched before we dispatch more. | |
| 177 if (!request_info->deferred_message_queue.empty()) { | |
| 178 FlushDeferredMessages(request_id); | |
| 179 request_info = GetPendingRequestInfo(request_id); | |
| 180 DCHECK(request_info); | |
| 181 if (request_info->is_deferred) { | |
| 182 request_info->deferred_message_queue.push_back(new IPC::Message(message)); | |
| 183 return true; | |
| 184 } | |
| 185 } | |
| 186 | 180 | 
| 187 DispatchMessage(message); | 181 DispatchMessage(message); | 
| 188 return true; | 182 return true; | 
| 189 } | 183 } | 
| 190 | 184 | 
| 191 ResourceDispatcher::PendingRequestInfo* | 185 ResourceDispatcher::PendingRequestInfo* | 
| 192 ResourceDispatcher::GetPendingRequestInfo(int request_id) { | 186 ResourceDispatcher::GetPendingRequestInfo(int request_id) { | 
| 193 PendingRequestMap::iterator it = pending_requests_.find(request_id); | 187 PendingRequestMap::iterator it = pending_requests_.find(request_id); | 
| 194 if (it == pending_requests_.end()) { | 188 if (it == pending_requests_.end()) { | 
| 195 // This might happen for kill()ed requests on the webkit end. | 189 // This might happen for kill()ed requests on the webkit end. | 
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 IPC_MESSAGE_HANDLER(ResourceMsg_SetDataBuffer, OnSetDataBuffer) | 567 IPC_MESSAGE_HANDLER(ResourceMsg_SetDataBuffer, OnSetDataBuffer) | 
| 574 IPC_MESSAGE_HANDLER(ResourceMsg_InlinedDataChunkReceived, | 568 IPC_MESSAGE_HANDLER(ResourceMsg_InlinedDataChunkReceived, | 
| 575 OnReceivedInlinedDataChunk) | 569 OnReceivedInlinedDataChunk) | 
| 576 IPC_MESSAGE_HANDLER(ResourceMsg_DataReceived, OnReceivedData) | 570 IPC_MESSAGE_HANDLER(ResourceMsg_DataReceived, OnReceivedData) | 
| 577 IPC_MESSAGE_HANDLER(ResourceMsg_DataDownloaded, OnDownloadedData) | 571 IPC_MESSAGE_HANDLER(ResourceMsg_DataDownloaded, OnDownloadedData) | 
| 578 IPC_MESSAGE_HANDLER(ResourceMsg_RequestComplete, OnRequestComplete) | 572 IPC_MESSAGE_HANDLER(ResourceMsg_RequestComplete, OnRequestComplete) | 
| 579 IPC_END_MESSAGE_MAP() | 573 IPC_END_MESSAGE_MAP() | 
| 580 } | 574 } | 
| 581 | 575 | 
| 582 void ResourceDispatcher::FlushDeferredMessages(int request_id) { | 576 void ResourceDispatcher::FlushDeferredMessages(int request_id) { | 
| 583 PendingRequestMap::iterator it = pending_requests_.find(request_id); | 577 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 
| 584 if (it == pending_requests_.end()) // The request could have become invalid. | 578 if (!request_info || request_info->is_deferred) | 
| 585 return; | |
| 586 PendingRequestInfo* request_info = it->second.get(); | |
| 587 if (request_info->is_deferred) | |
| 588 return; | 579 return; | 
| 589 // Because message handlers could result in request_info being destroyed, | 580 // Because message handlers could result in request_info being destroyed, | 
| 590 // we need to work with a stack reference to the deferred queue. | 581 // we need to work with a stack reference to the deferred queue. | 
| 591 MessageQueue q; | 582 MessageQueue q; | 
| 592 q.swap(request_info->deferred_message_queue); | 583 q.swap(request_info->deferred_message_queue); | 
| 593 while (!q.empty()) { | 584 while (!q.empty()) { | 
| 594 IPC::Message* m = q.front(); | 585 IPC::Message* m = q.front(); | 
| 595 q.pop_front(); | 586 q.pop_front(); | 
| 596 DispatchMessage(*m); | 587 DispatchMessage(*m); | 
| 597 delete m; | 588 delete m; | 
| 589 // We need to find the request again in the list as it may have completed | |
| 590 // by now and the request_info instance above may be invalid. | |
| 591 request_info = GetPendingRequestInfo(request_id); | |
| 592 if (!request_info) { | |
| 593 // The recipient is gone, the messages won't be handled and | |
| 594 // resources they might hold won't be released. Explicitly release | |
| 595 // them from here so that they won't leak. | |
| 596 ReleaseResourcesInMessageQueue(&q); | |
| 
kinuko
2016/10/19 13:35:53
I think if GetPendingRequestInfo returns null Rele
 
jb
2016/10/20 13:06:50
In this context the queue in the request_info is s
 | |
| 597 return; | |
| 598 } | |
| 598 // If this request is deferred in the context of the above message, then | 599 // If this request is deferred in the context of the above message, then | 
| 599 // we should honor the same and stop dispatching further messages. | 600 // we should honor the same and stop dispatching further messages. | 
| 600 // We need to find the request again in the list as it may have completed | 601 if (request_info->is_deferred) { | 
| 601 // by now and the request_info instance above may be invalid. | 602 request_info->deferred_message_queue.swap(q); | 
| 602 PendingRequestMap::iterator index = pending_requests_.find(request_id); | 603 return; | 
| 603 if (index != pending_requests_.end()) { | |
| 604 PendingRequestInfo* pending_request = index->second.get(); | |
| 605 if (pending_request->is_deferred) { | |
| 606 pending_request->deferred_message_queue.swap(q); | |
| 607 return; | |
| 608 } | |
| 609 } | 604 } | 
| 610 } | 605 } | 
| 611 } | 606 } | 
| 612 | 607 | 
| 613 void ResourceDispatcher::StartSync( | 608 void ResourceDispatcher::StartSync( | 
| 614 std::unique_ptr<ResourceRequest> request, | 609 std::unique_ptr<ResourceRequest> request, | 
| 615 int routing_id, | 610 int routing_id, | 
| 616 SyncLoadResponse* response, | 611 SyncLoadResponse* response, | 
| 617 blink::WebURLRequest::LoadingIPCType ipc_type, | 612 blink::WebURLRequest::LoadingIPCType ipc_type, | 
| 618 mojom::URLLoaderFactory* url_loader_factory) { | 613 mojom::URLLoaderFactory* url_loader_factory) { | 
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 819 delete message; | 814 delete message; | 
| 820 } | 815 } | 
| 821 } | 816 } | 
| 822 | 817 | 
| 823 void ResourceDispatcher::SetResourceSchedulingFilter( | 818 void ResourceDispatcher::SetResourceSchedulingFilter( | 
| 824 scoped_refptr<ResourceSchedulingFilter> resource_scheduling_filter) { | 819 scoped_refptr<ResourceSchedulingFilter> resource_scheduling_filter) { | 
| 825 resource_scheduling_filter_ = resource_scheduling_filter; | 820 resource_scheduling_filter_ = resource_scheduling_filter; | 
| 826 } | 821 } | 
| 827 | 822 | 
| 828 } // namespace content | 823 } // namespace content | 
| OLD | NEW |