Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: content/child/url_loader_client_impl.cc

Issue 2591383003: Implement SetDefersLoading on content::URLLoaderClientImpl (Closed)
Patch Set: fix Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 #include "content/child/url_loader_client_impl.h" 5 #include "content/child/url_loader_client_impl.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/single_thread_task_runner.h" 8 #include "base/single_thread_task_runner.h"
9 #include "content/child/resource_dispatcher.h" 9 #include "content/child/resource_dispatcher.h"
10 #include "content/child/url_response_body_consumer.h" 10 #include "content/child/url_response_body_consumer.h"
11 #include "content/common/resource_messages.h" 11 #include "content/common/resource_messages.h"
12 #include "mojo/public/cpp/bindings/associated_group.h" 12 #include "mojo/public/cpp/bindings/associated_group.h"
13 #include "net/url_request/redirect_info.h" 13 #include "net/url_request/redirect_info.h"
14 14
15 namespace content { 15 namespace content {
16 16
17 URLLoaderClientImpl::URLLoaderClientImpl( 17 URLLoaderClientImpl::URLLoaderClientImpl(
18 int request_id, 18 int request_id,
19 ResourceDispatcher* resource_dispatcher, 19 ResourceDispatcher* resource_dispatcher,
20 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 20 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
21 : binding_(this), 21 : binding_(this),
22 request_id_(request_id), 22 request_id_(request_id),
23 resource_dispatcher_(resource_dispatcher), 23 resource_dispatcher_(resource_dispatcher),
24 is_destroyed_(new base::RefCountedData<bool>(false)),
24 task_runner_(std::move(task_runner)) {} 25 task_runner_(std::move(task_runner)) {}
25 26
26 URLLoaderClientImpl::~URLLoaderClientImpl() { 27 URLLoaderClientImpl::~URLLoaderClientImpl() {
27 if (body_consumer_) 28 if (body_consumer_)
28 body_consumer_->Cancel(); 29 body_consumer_->Cancel();
30 is_destroyed_->data = true;
29 } 31 }
30 32
31 void URLLoaderClientImpl::Bind( 33 void URLLoaderClientImpl::Bind(
32 mojom::URLLoaderClientAssociatedPtrInfo* client_ptr_info, 34 mojom::URLLoaderClientAssociatedPtrInfo* client_ptr_info,
33 mojo::AssociatedGroup* associated_group) { 35 mojo::AssociatedGroup* associated_group) {
34 binding_.Bind(client_ptr_info, associated_group); 36 binding_.Bind(client_ptr_info, associated_group);
35 } 37 }
36 38
39 void URLLoaderClientImpl::SetDefersLoading() {
40 is_deferred_ = true;
41 if (body_consumer_)
42 body_consumer_->SetDefersLoading();
43 }
44
45 void URLLoaderClientImpl::UnsetDefersLoading() {
46 is_deferred_ = false;
47 }
48
49 void URLLoaderClientImpl::FlushDeferredMessages() {
50 DCHECK(!is_deferred_);
51 std::vector<IPC::Message> messages;
52 messages.swap(deferred_messages_);
53 bool has_completion_message = false;
54 scoped_refptr<base::RefCountedData<bool>> is_destroyed = is_destroyed_;
55 size_t index = 0;
56 // First, dispatch all messages excluding the followings:
57 // - response body (dispatched by |body_consumer_|)
58 // - transfer size change (dispatched later)
59 // - completion (dispatched by |body_consumer_| or dispatched later)
60 for (index = 0; index < messages.size(); ++index) {
61 if (messages[index].type() == ResourceMsg_RequestComplete::ID) {
62 // The completion message arrives at the end of the message queue.
63 DCHECK(!has_completion_message);
64 DCHECK_EQ(index, messages.size() - 1);
65 has_completion_message = true;
66 } else {
67 Dispatch(messages[index]);
68 }
69 if (is_destroyed->data)
kinuko 2016/12/23 13:11:23 Looking into the usage, I think using WeakPtr is p
yhirano 2016/12/26 05:08:35 Done.
70 return;
71 if (is_deferred_) {
72 deferred_messages_.insert(deferred_messages_.begin(),
73 messages.begin() + index + 1, messages.end());
74 return;
75 }
76 }
77
78 // Dispatch the transfer size update.
79 if (accumulated_transfer_size_diff_during_deferred_ > 0) {
80 auto transfer_size_diff = accumulated_transfer_size_diff_during_deferred_;
81 accumulated_transfer_size_diff_during_deferred_ = 0;
82 resource_dispatcher_->OnTransferSizeUpdated(request_id_,
83 transfer_size_diff);
84 if (is_destroyed->data)
85 return;
86 if (is_deferred_) {
87 deferred_messages_.insert(deferred_messages_.begin(),
88 messages.begin() + index, messages.end());
kinuko 2016/12/23 13:11:23 I'm a little confused, we don't break the for loop
yhirano 2016/12/26 05:08:35 Oops, sorry. Fixed.
kinuko 2016/12/26 07:21:17 Thanks. Should we have a test that must have caugh
yhirano 2016/12/26 08:22:00 Done.
89 return;
90 }
91 }
92
93 if (body_consumer_) {
94 // Dispatch the response body.
95 body_consumer_->UnsetDefersLoading();
96 if (is_destroyed->data)
97 return;
98 if (is_deferred_) {
99 deferred_messages_.insert(deferred_messages_.begin(),
100 messages.begin() + index, messages.end());
101 return;
102 }
103 }
104
105 // Dispatch the completion message.
106 if (has_completion_message) {
107 DCHECK_GT(messages.size(), 0u);
108 DCHECK_EQ(messages.back().type(),
109 static_cast<uint32_t>(ResourceMsg_RequestComplete::ID));
110 Dispatch(messages.back());
111 }
112 }
113
37 void URLLoaderClientImpl::OnReceiveResponse( 114 void URLLoaderClientImpl::OnReceiveResponse(
38 const ResourceResponseHead& response_head, 115 const ResourceResponseHead& response_head,
39 mojom::DownloadedTempFilePtr downloaded_file) { 116 mojom::DownloadedTempFilePtr downloaded_file) {
40 has_received_response_ = true; 117 has_received_response_ = true;
41 if (body_consumer_) 118 if (body_consumer_)
42 body_consumer_->Start(); 119 body_consumer_->Start();
43 downloaded_file_ = std::move(downloaded_file); 120 downloaded_file_ = std::move(downloaded_file);
44 Dispatch(ResourceMsg_ReceivedResponse(request_id_, response_head)); 121 Dispatch(ResourceMsg_ReceivedResponse(request_id_, response_head));
45 } 122 }
46 123
47 void URLLoaderClientImpl::OnReceiveRedirect( 124 void URLLoaderClientImpl::OnReceiveRedirect(
48 const net::RedirectInfo& redirect_info, 125 const net::RedirectInfo& redirect_info,
49 const ResourceResponseHead& response_head) { 126 const ResourceResponseHead& response_head) {
50 DCHECK(!has_received_response_); 127 DCHECK(!has_received_response_);
51 DCHECK(!body_consumer_); 128 DCHECK(!body_consumer_);
52 Dispatch( 129 Dispatch(
53 ResourceMsg_ReceivedRedirect(request_id_, redirect_info, response_head)); 130 ResourceMsg_ReceivedRedirect(request_id_, redirect_info, response_head));
54 } 131 }
55 132
56 void URLLoaderClientImpl::OnDataDownloaded(int64_t data_len, 133 void URLLoaderClientImpl::OnDataDownloaded(int64_t data_len,
57 int64_t encoded_data_len) { 134 int64_t encoded_data_len) {
58 Dispatch(ResourceMsg_DataDownloaded(request_id_, data_len, encoded_data_len)); 135 Dispatch(ResourceMsg_DataDownloaded(request_id_, data_len, encoded_data_len));
59 } 136 }
60 137
61 void URLLoaderClientImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) { 138 void URLLoaderClientImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) {
62 resource_dispatcher_->OnTransferSizeUpdated(request_id_, 139 if (is_deferred_) {
63 transfer_size_diff); 140 accumulated_transfer_size_diff_during_deferred_ += transfer_size_diff;
141 } else {
142 resource_dispatcher_->OnTransferSizeUpdated(request_id_,
143 transfer_size_diff);
144 }
64 } 145 }
65 146
66 void URLLoaderClientImpl::OnStartLoadingResponseBody( 147 void URLLoaderClientImpl::OnStartLoadingResponseBody(
67 mojo::ScopedDataPipeConsumerHandle body) { 148 mojo::ScopedDataPipeConsumerHandle body) {
68 DCHECK(!body_consumer_); 149 DCHECK(!body_consumer_);
69 body_consumer_ = new URLResponseBodyConsumer( 150 body_consumer_ = new URLResponseBodyConsumer(
70 request_id_, resource_dispatcher_, std::move(body), task_runner_); 151 request_id_, resource_dispatcher_, std::move(body), task_runner_);
71 if (has_received_response_) 152 if (has_received_response_)
72 body_consumer_->Start(); 153 body_consumer_->Start();
154 if (is_deferred_)
155 body_consumer_->SetDefersLoading();
73 } 156 }
74 157
75 void URLLoaderClientImpl::OnComplete( 158 void URLLoaderClientImpl::OnComplete(
76 const ResourceRequestCompletionStatus& status) { 159 const ResourceRequestCompletionStatus& status) {
77 if (!body_consumer_) { 160 if (!body_consumer_) {
78 Dispatch(ResourceMsg_RequestComplete(request_id_, status)); 161 Dispatch(ResourceMsg_RequestComplete(request_id_, status));
79 return; 162 return;
80 } 163 }
81 body_consumer_->OnComplete(status); 164 body_consumer_->OnComplete(status);
82 } 165 }
83 166
84 void URLLoaderClientImpl::Dispatch(const IPC::Message& message) { 167 void URLLoaderClientImpl::Dispatch(const IPC::Message& message) {
85 resource_dispatcher_->OnMessageReceived(message); 168 if (is_deferred_) {
169 deferred_messages_.push_back(message);
170 } else if (deferred_messages_.size() > 0) {
171 deferred_messages_.push_back(message);
172 FlushDeferredMessages();
173 } else {
174 resource_dispatcher_->OnMessageReceived(message);
kinuko 2016/12/23 13:11:23 At this point couldn't we directly call ResourceDi
yhirano 2016/12/26 05:08:35 ResourceDispatcher::DispatchMessage is a private m
kinuko 2016/12/26 07:21:17 But eventually we plan to get rid of OnMessageRece
yhirano 2016/12/26 08:22:00 Done.
175 }
86 } 176 }
87 177
88 } // namespace content 178 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698