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

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

Issue 109283006: Redirect HTML resource bytes directly to parser thread (Chrome side CL) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 9 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/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/memory/shared_memory.h" 14 #include "base/memory/shared_memory.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
18 #include "content/child/request_extra_data.h" 18 #include "content/child/request_extra_data.h"
19 #include "content/child/site_isolation_policy.h" 19 #include "content/child/site_isolation_policy.h"
20 #include "content/child/threadeddataprovider.h"
20 #include "content/common/inter_process_time_ticks_converter.h" 21 #include "content/common/inter_process_time_ticks_converter.h"
21 #include "content/common/resource_messages.h" 22 #include "content/common/resource_messages.h"
22 #include "content/common/service_worker/service_worker_types.h" 23 #include "content/common/service_worker/service_worker_types.h"
23 #include "content/public/child/resource_dispatcher_delegate.h" 24 #include "content/public/child/resource_dispatcher_delegate.h"
24 #include "content/public/common/resource_response.h" 25 #include "content/public/common/resource_response.h"
25 #include "net/base/net_errors.h" 26 #include "net/base/net_errors.h"
26 #include "net/base/net_util.h" 27 #include "net/base/net_util.h"
27 #include "net/base/request_priority.h" 28 #include "net/base/request_priority.h"
28 #include "net/http/http_response_headers.h" 29 #include "net/http/http_response_headers.h"
29 #include "webkit/common/resource_type.h" 30 #include "webkit/common/resource_type.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 IPCResourceLoaderBridge(ResourceDispatcher* dispatcher, 72 IPCResourceLoaderBridge(ResourceDispatcher* dispatcher,
72 const ResourceLoaderBridge::RequestInfo& request_info); 73 const ResourceLoaderBridge::RequestInfo& request_info);
73 virtual ~IPCResourceLoaderBridge(); 74 virtual ~IPCResourceLoaderBridge();
74 75
75 // ResourceLoaderBridge 76 // ResourceLoaderBridge
76 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; 77 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE;
77 virtual bool Start(Peer* peer) OVERRIDE; 78 virtual bool Start(Peer* peer) OVERRIDE;
78 virtual void Cancel() OVERRIDE; 79 virtual void Cancel() OVERRIDE;
79 virtual void SetDefersLoading(bool value) OVERRIDE; 80 virtual void SetDefersLoading(bool value) OVERRIDE;
80 virtual void DidChangePriority(net::RequestPriority new_priority) OVERRIDE; 81 virtual void DidChangePriority(net::RequestPriority new_priority) OVERRIDE;
82 virtual bool AttachThreadedDataReceiver(
83 blink::WebThreadedDataReceiver* threaded_data_receiver) OVERRIDE;
81 virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE; 84 virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE;
82 85
83 private: 86 private:
84 ResourceLoaderBridge::Peer* peer_; 87 ResourceLoaderBridge::Peer* peer_;
85 88
86 // The resource dispatcher for this loader. The bridge doesn't own it, but 89 // The resource dispatcher for this loader. The bridge doesn't own it, but
87 // it's guaranteed to outlive the bridge. 90 // it's guaranteed to outlive the bridge.
88 ResourceDispatcher* dispatcher_; 91 ResourceDispatcher* dispatcher_;
89 92
90 // The request to send, created on initialization for modification and 93 // The request to send, created on initialization for modification and
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 void IPCResourceLoaderBridge::DidChangePriority( 230 void IPCResourceLoaderBridge::DidChangePriority(
228 net::RequestPriority new_priority) { 231 net::RequestPriority new_priority) {
229 if (request_id_ < 0) { 232 if (request_id_ < 0) {
230 NOTREACHED() << "Trying to change priority of an unstarted request"; 233 NOTREACHED() << "Trying to change priority of an unstarted request";
231 return; 234 return;
232 } 235 }
233 236
234 dispatcher_->DidChangePriority(routing_id_, request_id_, new_priority); 237 dispatcher_->DidChangePriority(routing_id_, request_id_, new_priority);
235 } 238 }
236 239
240 bool IPCResourceLoaderBridge::AttachThreadedDataReceiver(
241 blink::WebThreadedDataReceiver* threaded_data_receiver) {
242 if (request_id_ < 0) {
243 NOTREACHED() << "Trying to attach threaded receiver on unstarted request";
244 return false;
245 }
246
247 return dispatcher_->AttachThreadedDataReceiver(request_id_,
248 threaded_data_receiver);
249 }
250
237 void IPCResourceLoaderBridge::SyncLoad(SyncLoadResponse* response) { 251 void IPCResourceLoaderBridge::SyncLoad(SyncLoadResponse* response) {
238 if (request_id_ != -1) { 252 if (request_id_ != -1) {
239 NOTREACHED() << "Starting a request twice"; 253 NOTREACHED() << "Starting a request twice";
240 response->error_code = net::ERR_FAILED; 254 response->error_code = net::ERR_FAILED;
241 return; 255 return;
242 } 256 }
243 257
244 request_id_ = MakeRequestID(); 258 request_id_ = MakeRequestID();
245 is_synchronous_request_ = true; 259 is_synchronous_request_ = true;
246 260
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 request_info->buffer_size = shm_size; 426 request_info->buffer_size = shm_size;
413 } 427 }
414 428
415 void ResourceDispatcher::OnReceivedData(int request_id, 429 void ResourceDispatcher::OnReceivedData(int request_id,
416 int data_offset, 430 int data_offset,
417 int data_length, 431 int data_length,
418 int encoded_data_length) { 432 int encoded_data_length) {
419 TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedData"); 433 TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedData");
420 DCHECK_GT(data_length, 0); 434 DCHECK_GT(data_length, 0);
421 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 435 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
436 bool send_ack = true;
422 if (request_info && data_length > 0) { 437 if (request_info && data_length > 0) {
423 CHECK(base::SharedMemory::IsHandleValid(request_info->buffer->handle())); 438 CHECK(base::SharedMemory::IsHandleValid(request_info->buffer->handle()));
424 CHECK_GE(request_info->buffer_size, data_offset + data_length); 439 CHECK_GE(request_info->buffer_size, data_offset + data_length);
425 440
426 // Ensure that the SHM buffer remains valid for the duration of this scope. 441 // Ensure that the SHM buffer remains valid for the duration of this scope.
427 // It is possible for CancelPendingRequest() to be called before we exit 442 // It is possible for CancelPendingRequest() to be called before we exit
428 // this scope. 443 // this scope.
429 linked_ptr<base::SharedMemory> retain_buffer(request_info->buffer); 444 linked_ptr<base::SharedMemory> retain_buffer(request_info->buffer);
430 445
431 base::TimeTicks time_start = base::TimeTicks::Now(); 446 base::TimeTicks time_start = base::TimeTicks::Now();
432 447
433 const char* data_ptr = static_cast<char*>(request_info->buffer->memory()); 448 const char* data_start = static_cast<char*>(request_info->buffer->memory());
434 CHECK(data_ptr); 449 CHECK(data_start);
435 CHECK(data_ptr + data_offset); 450 CHECK(data_start + data_offset);
451 const char* data_ptr = data_start + data_offset;
436 452
437 // Check whether this response data is compliant with our cross-site 453 // Check whether this response data is compliant with our cross-site
438 // document blocking policy. We only do this for the first packet. 454 // document blocking policy. We only do this for the first packet.
439 std::string alternative_data; 455 std::string alternative_data;
440 if (request_info->site_isolation_metadata.get()) { 456 if (request_info->site_isolation_metadata.get()) {
441 request_info->blocked_response = 457 request_info->blocked_response =
442 SiteIsolationPolicy::ShouldBlockResponse( 458 SiteIsolationPolicy::ShouldBlockResponse(
443 request_info->site_isolation_metadata, data_ptr + data_offset, 459 request_info->site_isolation_metadata, data_ptr, data_length,
444 data_length, &alternative_data); 460 &alternative_data);
445 request_info->site_isolation_metadata.reset(); 461 request_info->site_isolation_metadata.reset();
462
463 // When the response is blocked we may have any alternative data to
464 // send to the renderer. When |alternative_data| is zero-sized, we do not
465 // call peer's callback.
466 if (request_info->blocked_response && alternative_data.size() > 0) {
darin (slow to review) 2014/03/31 17:00:01 nit: it is generally preferred with STL to do !con
467 data_ptr = alternative_data.data();
468 data_length = alternative_data.size();
469 encoded_data_length = alternative_data.size();
470 }
446 } 471 }
447 472
448 // When the response is not blocked. 473 if (!request_info->blocked_response || alternative_data.size() > 0) {
darin (slow to review) 2014/03/31 17:00:01 ditto
449 if (!request_info->blocked_response) { 474 if (request_info->threaded_data_provider) {
450 request_info->peer->OnReceivedData( 475 request_info->threaded_data_provider->OnReceivedDataOnForegroundThread(
451 data_ptr + data_offset, data_length, encoded_data_length); 476 data_ptr, data_length, encoded_data_length);
452 } else if (alternative_data.size() > 0) { 477 // A threaded data provider will take care of its own ACKing, as the
453 // When the response is blocked, and when we have any alternative data to 478 // data may be processed later on another thread.
454 // send to the renderer. When |alternative_data| is zero-sized, we do not 479 send_ack = false;
455 // call peer's callback. 480 } else {
456 request_info->peer->OnReceivedData(alternative_data.data(), 481 request_info->peer->OnReceivedData(
457 alternative_data.size(), 482 data_ptr, data_length, encoded_data_length);
458 alternative_data.size()); 483 }
459 } 484 }
460 485
461 UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime", 486 UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime",
462 base::TimeTicks::Now() - time_start); 487 base::TimeTicks::Now() - time_start);
463 } 488 }
464 489
465 // Acknowledge the reception of this data. 490 // Acknowledge the reception of this data.
466 message_sender()->Send(new ResourceHostMsg_DataReceived_ACK(request_id)); 491 if (send_ack)
492 message_sender()->Send(new ResourceHostMsg_DataReceived_ACK(request_id));
467 } 493 }
468 494
469 void ResourceDispatcher::OnDownloadedData(int request_id, 495 void ResourceDispatcher::OnDownloadedData(int request_id,
470 int data_len, 496 int data_len,
471 int encoded_data_length) { 497 int encoded_data_length) {
472 // Acknowledge the reception of this message. 498 // Acknowledge the reception of this message.
473 message_sender()->Send( 499 message_sender()->Send(
474 new ResourceHostMsg_DataDownloaded_ACK(request_id)); 500 new ResourceHostMsg_DataDownloaded_ACK(request_id));
475 501
476 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 502 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 } 646 }
621 } 647 }
622 648
623 void ResourceDispatcher::DidChangePriority( 649 void ResourceDispatcher::DidChangePriority(
624 int routing_id, int request_id, net::RequestPriority new_priority) { 650 int routing_id, int request_id, net::RequestPriority new_priority) {
625 DCHECK(ContainsKey(pending_requests_, request_id)); 651 DCHECK(ContainsKey(pending_requests_, request_id));
626 message_sender()->Send(new ResourceHostMsg_DidChangePriority( 652 message_sender()->Send(new ResourceHostMsg_DidChangePriority(
627 request_id, new_priority)); 653 request_id, new_priority));
628 } 654 }
629 655
656 bool ResourceDispatcher::AttachThreadedDataReceiver(
657 int request_id, blink::WebThreadedDataReceiver* threaded_data_receiver) {
658 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
659 DCHECK(request_info);
660 DCHECK(!request_info->threaded_data_provider);
661 request_info->threaded_data_provider = new ThreadedDataProvider(
662 request_id, threaded_data_receiver, request_info->buffer,
663 request_info->buffer_size);
664
665 return true;
666 }
667
630 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() 668 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo()
631 : peer(NULL), 669 : peer(NULL),
670 threaded_data_provider(NULL),
632 resource_type(ResourceType::SUB_RESOURCE), 671 resource_type(ResourceType::SUB_RESOURCE),
633 is_deferred(false), 672 is_deferred(false),
634 blocked_response(false), 673 blocked_response(false),
635 buffer_size(0) { 674 buffer_size(0) {
636 } 675 }
637 676
638 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( 677 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
639 webkit_glue::ResourceLoaderBridge::Peer* peer, 678 webkit_glue::ResourceLoaderBridge::Peer* peer,
640 ResourceType::Type resource_type, 679 ResourceType::Type resource_type,
641 int origin_pid, 680 int origin_pid,
642 const GURL& frame_origin, 681 const GURL& frame_origin,
643 const GURL& request_url) 682 const GURL& request_url)
644 : peer(peer), 683 : peer(peer),
684 threaded_data_provider(NULL),
645 resource_type(resource_type), 685 resource_type(resource_type),
646 origin_pid(origin_pid), 686 origin_pid(origin_pid),
647 is_deferred(false), 687 is_deferred(false),
648 url(request_url), 688 url(request_url),
649 frame_origin(frame_origin), 689 frame_origin(frame_origin),
650 response_url(request_url), 690 response_url(request_url),
651 request_start(base::TimeTicks::Now()), 691 request_start(base::TimeTicks::Now()),
652 blocked_response(false) { 692 blocked_response(false) {
653 } 693 }
654 694
655 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} 695 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {
696 if (threaded_data_provider)
697 threaded_data_provider->Stop();
698 }
656 699
657 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { 700 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) {
658 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message) 701 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message)
659 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress) 702 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress)
660 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse) 703 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse)
661 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, 704 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata,
662 OnReceivedCachedMetadata) 705 OnReceivedCachedMetadata)
663 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedRedirect, OnReceivedRedirect) 706 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedRedirect, OnReceivedRedirect)
664 IPC_MESSAGE_HANDLER(ResourceMsg_SetDataBuffer, OnSetDataBuffer) 707 IPC_MESSAGE_HANDLER(ResourceMsg_SetDataBuffer, OnSetDataBuffer)
665 IPC_MESSAGE_HANDLER(ResourceMsg_DataReceived, OnReceivedData) 708 IPC_MESSAGE_HANDLER(ResourceMsg_DataReceived, OnReceivedData)
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { 853 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) {
811 while (!queue->empty()) { 854 while (!queue->empty()) {
812 IPC::Message* message = queue->front(); 855 IPC::Message* message = queue->front();
813 ReleaseResourcesInDataMessage(*message); 856 ReleaseResourcesInDataMessage(*message);
814 queue->pop_front(); 857 queue->pop_front();
815 delete message; 858 delete message;
816 } 859 }
817 } 860 }
818 861
819 } // namespace content 862 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698