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

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

Issue 1103813002: Make WebURLLoader capable of retaining received buffers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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 (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"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/debug/alias.h" 12 #include "base/debug/alias.h"
13 #include "base/debug/dump_without_crashing.h" 13 #include "base/debug/dump_without_crashing.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/memory/shared_memory.h" 15 #include "base/memory/shared_memory.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "content/child/ref_counted_shared_memory.h"
19 #include "content/child/request_extra_data.h" 20 #include "content/child/request_extra_data.h"
20 #include "content/child/request_info.h" 21 #include "content/child/request_info.h"
21 #include "content/child/site_isolation_policy.h" 22 #include "content/child/site_isolation_policy.h"
22 #include "content/child/sync_load_response.h" 23 #include "content/child/sync_load_response.h"
23 #include "content/child/threaded_data_provider.h" 24 #include "content/child/threaded_data_provider.h"
24 #include "content/common/inter_process_time_ticks_converter.h" 25 #include "content/common/inter_process_time_ticks_converter.h"
25 #include "content/common/resource_messages.h" 26 #include "content/common/resource_messages.h"
26 #include "content/public/child/request_peer.h" 27 #include "content/public/child/request_peer.h"
27 #include "content/public/child/resource_dispatcher_delegate.h" 28 #include "content/public/child/resource_dispatcher_delegate.h"
28 #include "content/public/common/resource_response.h" 29 #include "content/public/common/resource_response.h"
29 #include "content/public/common/resource_type.h" 30 #include "content/public/common/resource_type.h"
30 #include "net/base/net_errors.h" 31 #include "net/base/net_errors.h"
31 #include "net/base/net_util.h" 32 #include "net/base/net_util.h"
32 #include "net/base/request_priority.h" 33 #include "net/base/request_priority.h"
33 #include "net/http/http_response_headers.h" 34 #include "net/http/http_response_headers.h"
34 35
35 namespace content { 36 namespace content {
36 37
37 namespace { 38 namespace {
38 39
40 class SharedMemoryReceivedData final : public RequestPeer::ReceivedData {
41 public:
42 SharedMemoryReceivedData(const char* payload,
43 int length,
44 int encoded_length,
45 IPC::Sender* message_sender,
46 int request_id,
47 scoped_refptr<RefCountedSharedMemory> shm_buffer)
48 : payload_(payload),
49 length_(length),
50 encoded_length_(encoded_length),
51 message_sender_(message_sender),
52 request_id_(request_id),
53 shm_buffer_(shm_buffer) {}
54 ~SharedMemoryReceivedData() override {
55 message_sender_->Send(new ResourceHostMsg_DataReceived_ACK(request_id_));
56 }
57
58 const char* payload() const override { return payload_; }
59 int length() const override { return length_; }
60 int encoded_length() const override { return encoded_length_; }
61
62 private:
63 const char* const payload_;
64 const int length_;
65 const int encoded_length_;
66
67 // We assume that |message_sender_| outlives this object. This is true because
68 // the sender is provided from |ResourceDispatcher::sender_| and it's a
69 // ChildThreadImpl.
70 IPC::Sender* const message_sender_;
71 const int request_id_;
72 // Just to keep |payload_| alive while this object is alive.
73 scoped_refptr<RefCountedSharedMemory> shm_buffer_;
74
75 DISALLOW_COPY_AND_ASSIGN(SharedMemoryReceivedData);
76 };
77
39 // Converts |time| from a remote to local TimeTicks, overwriting the original 78 // Converts |time| from a remote to local TimeTicks, overwriting the original
40 // value. 79 // value.
41 void RemoteToLocalTimeTicks( 80 void RemoteToLocalTimeTicks(
42 const InterProcessTimeTicksConverter& converter, 81 const InterProcessTimeTicksConverter& converter,
43 base::TimeTicks* time) { 82 base::TimeTicks* time) {
44 RemoteTimeTicks remote_time = RemoteTimeTicks::FromTimeTicks(*time); 83 RemoteTimeTicks remote_time = RemoteTimeTicks::FromTimeTicks(*time);
45 *time = converter.ToLocalTimeTicks(remote_time).ToTimeTicks(); 84 *time = converter.ToLocalTimeTicks(remote_time).ToTimeTicks();
46 } 85 }
47 86
48 void CrashOnMapFailure() { 87 void CrashOnMapFailure() {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 int shm_size, 221 int shm_size,
183 base::ProcessId renderer_pid) { 222 base::ProcessId renderer_pid) {
184 TRACE_EVENT0("loader", "ResourceDispatcher::OnSetDataBuffer"); 223 TRACE_EVENT0("loader", "ResourceDispatcher::OnSetDataBuffer");
185 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 224 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
186 if (!request_info) 225 if (!request_info)
187 return; 226 return;
188 227
189 bool shm_valid = base::SharedMemory::IsHandleValid(shm_handle); 228 bool shm_valid = base::SharedMemory::IsHandleValid(shm_handle);
190 CHECK((shm_valid && shm_size > 0) || (!shm_valid && !shm_size)); 229 CHECK((shm_valid && shm_size > 0) || (!shm_valid && !shm_size));
191 230
192 request_info->buffer.reset( 231 request_info->buffer = make_scoped_refptr(
193 new base::SharedMemory(shm_handle, true)); // read only 232 new RefCountedSharedMemory(shm_handle, true)); // read only
194 233
195 bool ok = request_info->buffer->Map(shm_size); 234 bool ok = request_info->buffer->memory().Map(shm_size);
196 if (!ok) { 235 if (!ok) {
197 // Added to help debug crbug/160401. 236 // Added to help debug crbug/160401.
198 base::ProcessId renderer_pid_copy = renderer_pid; 237 base::ProcessId renderer_pid_copy = renderer_pid;
199 base::debug::Alias(&renderer_pid_copy); 238 base::debug::Alias(&renderer_pid_copy);
200 239
201 base::SharedMemoryHandle shm_handle_copy = shm_handle; 240 base::SharedMemoryHandle shm_handle_copy = shm_handle;
202 base::debug::Alias(&shm_handle_copy); 241 base::debug::Alias(&shm_handle_copy);
203 242
204 CrashOnMapFailure(); 243 CrashOnMapFailure();
205 return; 244 return;
206 } 245 }
207 246
208 request_info->buffer_size = shm_size; 247 request_info->buffer_size = shm_size;
209 } 248 }
210 249
211 void ResourceDispatcher::OnReceivedData(int request_id, 250 void ResourceDispatcher::OnReceivedData(int request_id,
212 int data_offset, 251 int data_offset,
213 int data_length, 252 int data_length,
214 int encoded_data_length) { 253 int encoded_data_length) {
215 TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedData"); 254 TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedData");
216 DCHECK_GT(data_length, 0); 255 DCHECK_GT(data_length, 0);
217 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 256 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
218 bool send_ack = true; 257 bool send_ack = true;
219 if (request_info && data_length > 0) { 258 if (request_info && data_length > 0) {
220 CHECK(base::SharedMemory::IsHandleValid(request_info->buffer->handle())); 259 CHECK(base::SharedMemory::IsHandleValid(
260 request_info->buffer->memory().handle()));
221 CHECK_GE(request_info->buffer_size, data_offset + data_length); 261 CHECK_GE(request_info->buffer_size, data_offset + data_length);
222 262
223 // Ensure that the SHM buffer remains valid for the duration of this scope. 263 // Ensure that the SHM buffer remains valid for the duration of this scope.
224 // It is possible for Cancel() to be called before we exit this scope. 264 // It is possible for Cancel() to be called before we exit this scope.
225 linked_ptr<base::SharedMemory> retain_buffer(request_info->buffer); 265 scoped_refptr<RefCountedSharedMemory> retain_buffer(request_info->buffer);
226 266
227 base::TimeTicks time_start = base::TimeTicks::Now(); 267 base::TimeTicks time_start = base::TimeTicks::Now();
228 268
229 const char* data_start = static_cast<char*>(request_info->buffer->memory()); 269 const char* data_start =
270 static_cast<char*>(request_info->buffer->memory().memory());
230 CHECK(data_start); 271 CHECK(data_start);
231 CHECK(data_start + data_offset); 272 CHECK(data_start + data_offset);
232 const char* data_ptr = data_start + data_offset; 273 const char* data_ptr = data_start + data_offset;
233 274
234 // Check whether this response data is compliant with our cross-site 275 // Check whether this response data is compliant with our cross-site
235 // document blocking policy. We only do this for the first packet. 276 // document blocking policy. We only do this for the first packet.
236 std::string alternative_data; 277 std::string alternative_data;
237 if (request_info->site_isolation_metadata.get()) { 278 if (request_info->site_isolation_metadata.get()) {
238 request_info->blocked_response = 279 request_info->blocked_response =
239 SiteIsolationPolicy::ShouldBlockResponse( 280 SiteIsolationPolicy::ShouldBlockResponse(
(...skipping 12 matching lines...) Expand all
252 } 293 }
253 294
254 if (!request_info->blocked_response || !alternative_data.empty()) { 295 if (!request_info->blocked_response || !alternative_data.empty()) {
255 if (request_info->threaded_data_provider) { 296 if (request_info->threaded_data_provider) {
256 request_info->threaded_data_provider->OnReceivedDataOnForegroundThread( 297 request_info->threaded_data_provider->OnReceivedDataOnForegroundThread(
257 data_ptr, data_length, encoded_data_length); 298 data_ptr, data_length, encoded_data_length);
258 // A threaded data provider will take care of its own ACKing, as the 299 // A threaded data provider will take care of its own ACKing, as the
259 // data may be processed later on another thread. 300 // data may be processed later on another thread.
260 send_ack = false; 301 send_ack = false;
261 } else { 302 } else {
303 // The SharedMemoryReceivedData sends the ack signal on destruction.
304 send_ack = false;
305 // It's OK to pass the buffer because we don't use |data_ptr| in this
306 // function from now.
262 request_info->peer->OnReceivedData( 307 request_info->peer->OnReceivedData(
263 data_ptr, data_length, encoded_data_length); 308 make_scoped_ptr(new SharedMemoryReceivedData(
309 data_ptr, data_length, encoded_data_length, message_sender_,
310 request_id, retain_buffer.Pass())));
264 } 311 }
265 } 312 }
266 313
267 UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime", 314 UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime",
268 base::TimeTicks::Now() - time_start); 315 base::TimeTicks::Now() - time_start);
269 } 316 }
270 317
271 // Acknowledge the reception of this data. 318 // Acknowledge the reception of this data.
272 if (send_ack) 319 if (send_ack)
273 message_sender_->Send(new ResourceHostMsg_DataReceived_ACK(request_id)); 320 message_sender_->Send(new ResourceHostMsg_DataReceived_ACK(request_id));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 375
329 void ResourceDispatcher::OnRequestComplete( 376 void ResourceDispatcher::OnRequestComplete(
330 int request_id, 377 int request_id,
331 const ResourceMsg_RequestCompleteData& request_complete_data) { 378 const ResourceMsg_RequestCompleteData& request_complete_data) {
332 TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete"); 379 TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete");
333 380
334 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 381 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
335 if (!request_info) 382 if (!request_info)
336 return; 383 return;
337 request_info->completion_time = ConsumeIOTimestamp(); 384 request_info->completion_time = ConsumeIOTimestamp();
338 request_info->buffer.reset(); 385 request_info->buffer = nullptr;
339 request_info->buffer_size = 0; 386 request_info->buffer_size = 0;
340 387
341 RequestPeer* peer = request_info->peer; 388 RequestPeer* peer = request_info->peer;
342 389
343 if (delegate_) { 390 if (delegate_) {
344 RequestPeer* new_peer = 391 RequestPeer* new_peer =
345 delegate_->OnRequestComplete( 392 delegate_->OnRequestComplete(
346 request_info->peer, request_info->resource_type, 393 request_info->peer, request_info->resource_type,
347 request_complete_data.error_code); 394 request_complete_data.error_code);
348 if (new_peer) 395 if (new_peer)
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 extra_data->transferred_request_request_id(); 842 extra_data->transferred_request_request_id();
796 request->service_worker_provider_id = 843 request->service_worker_provider_id =
797 extra_data->service_worker_provider_id(); 844 extra_data->service_worker_provider_id();
798 request->request_body = request_body; 845 request->request_body = request_body;
799 if (frame_origin) 846 if (frame_origin)
800 *frame_origin = extra_data->frame_origin(); 847 *frame_origin = extra_data->frame_origin();
801 return request.Pass(); 848 return request.Pass();
802 } 849 }
803 850
804 } // namespace content 851 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698