| 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/common/resource_dispatcher.h" | 7 #include "content/common/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/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
| 14 #include "base/metrics/histogram.h" |
| 14 #include "base/shared_memory.h" | 15 #include "base/shared_memory.h" |
| 15 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 16 #include "content/common/inter_process_time_ticks_converter.h" | 17 #include "content/common/inter_process_time_ticks_converter.h" |
| 17 #include "content/common/request_extra_data.h" | 18 #include "content/common/request_extra_data.h" |
| 18 #include "content/common/resource_messages.h" | 19 #include "content/common/resource_messages.h" |
| 19 #include "content/public/common/resource_dispatcher_delegate.h" | 20 #include "content/public/common/resource_dispatcher_delegate.h" |
| 20 #include "content/public/common/resource_response.h" | 21 #include "content/public/common/resource_response.h" |
| 21 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 22 #include "net/base/net_util.h" | 23 #include "net/base/net_util.h" |
| 23 #include "net/http/http_response_headers.h" | 24 #include "net/http/http_response_headers.h" |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 void ResourceDispatcher::OnReceivedCachedMetadata( | 318 void ResourceDispatcher::OnReceivedCachedMetadata( |
| 318 int request_id, const std::vector<char>& data) { | 319 int request_id, const std::vector<char>& data) { |
| 319 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 320 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
| 320 if (!request_info) | 321 if (!request_info) |
| 321 return; | 322 return; |
| 322 | 323 |
| 323 if (data.size()) | 324 if (data.size()) |
| 324 request_info->peer->OnReceivedCachedMetadata(&data.front(), data.size()); | 325 request_info->peer->OnReceivedCachedMetadata(&data.front(), data.size()); |
| 325 } | 326 } |
| 326 | 327 |
| 328 void ResourceDispatcher::OnSetDataBuffer(const IPC::Message& message, |
| 329 int request_id, |
| 330 base::SharedMemoryHandle shm_handle, |
| 331 int shm_size) { |
| 332 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
| 333 if (!request_info) |
| 334 return; |
| 335 |
| 336 bool shm_valid = base::SharedMemory::IsHandleValid(shm_handle); |
| 337 DCHECK((shm_valid && shm_size > 0) || (!shm_valid && !shm_size)); |
| 338 |
| 339 request_info->buffer.reset( |
| 340 new base::SharedMemory(shm_handle, true)); // read only |
| 341 request_info->buffer->Map(shm_size); |
| 342 } |
| 343 |
| 327 void ResourceDispatcher::OnReceivedData(const IPC::Message& message, | 344 void ResourceDispatcher::OnReceivedData(const IPC::Message& message, |
| 328 int request_id, | 345 int request_id, |
| 329 base::SharedMemoryHandle shm_handle, | 346 int data_offset, |
| 330 int data_len, | 347 int data_length, |
| 331 int encoded_data_length) { | 348 int encoded_data_length) { |
| 349 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
| 350 if (request_info && data_length > 0) { |
| 351 base::TimeTicks time_start = base::TimeTicks::Now(); |
| 352 |
| 353 request_info->peer->OnReceivedData( |
| 354 static_cast<char*>(request_info->buffer->memory()) + data_offset, |
| 355 data_length, |
| 356 encoded_data_length); |
| 357 |
| 358 UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime", |
| 359 base::TimeTicks::Now() - time_start); |
| 360 } |
| 361 |
| 332 // Acknowledge the reception of this data. | 362 // Acknowledge the reception of this data. |
| 333 message_sender()->Send( | 363 message_sender()->Send( |
| 334 new ResourceHostMsg_DataReceived_ACK(message.routing_id(), request_id)); | 364 new ResourceHostMsg_DataReceived_ACK(message.routing_id(), request_id)); |
| 335 | |
| 336 const bool shm_valid = base::SharedMemory::IsHandleValid(shm_handle); | |
| 337 DCHECK((shm_valid && data_len > 0) || (!shm_valid && !data_len)); | |
| 338 base::SharedMemory shared_mem(shm_handle, true); // read only | |
| 339 | |
| 340 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | |
| 341 if (!request_info) | |
| 342 return; | |
| 343 | |
| 344 if (data_len > 0 && shared_mem.Map(data_len)) { | |
| 345 const char* data = static_cast<char*>(shared_mem.memory()); | |
| 346 request_info->peer->OnReceivedData(data, data_len, encoded_data_length); | |
| 347 } | |
| 348 } | 365 } |
| 349 | 366 |
| 350 void ResourceDispatcher::OnDownloadedData(const IPC::Message& message, | 367 void ResourceDispatcher::OnDownloadedData(const IPC::Message& message, |
| 351 int request_id, | 368 int request_id, |
| 352 int data_len) { | 369 int data_len) { |
| 353 // Acknowledge the reception of this message. | 370 // Acknowledge the reception of this message. |
| 354 message_sender()->Send( | 371 message_sender()->Send( |
| 355 new ResourceHostMsg_DataDownloaded_ACK(message.routing_id(), request_id)); | 372 new ResourceHostMsg_DataDownloaded_ACK(message.routing_id(), request_id)); |
| 356 | 373 |
| 357 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 374 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 void ResourceDispatcher::OnRequestComplete( | 424 void ResourceDispatcher::OnRequestComplete( |
| 408 int request_id, | 425 int request_id, |
| 409 int error_code, | 426 int error_code, |
| 410 bool was_ignored_by_handler, | 427 bool was_ignored_by_handler, |
| 411 const std::string& security_info, | 428 const std::string& security_info, |
| 412 const base::TimeTicks& browser_completion_time) { | 429 const base::TimeTicks& browser_completion_time) { |
| 413 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 430 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
| 414 if (!request_info) | 431 if (!request_info) |
| 415 return; | 432 return; |
| 416 request_info->completion_time = base::TimeTicks::Now(); | 433 request_info->completion_time = base::TimeTicks::Now(); |
| 434 request_info->buffer.reset(); |
| 417 | 435 |
| 418 ResourceLoaderBridge::Peer* peer = request_info->peer; | 436 ResourceLoaderBridge::Peer* peer = request_info->peer; |
| 419 | 437 |
| 420 if (delegate_) { | 438 if (delegate_) { |
| 421 ResourceLoaderBridge::Peer* new_peer = | 439 ResourceLoaderBridge::Peer* new_peer = |
| 422 delegate_->OnRequestComplete( | 440 delegate_->OnRequestComplete( |
| 423 request_info->peer, request_info->resource_type, error_code); | 441 request_info->peer, request_info->resource_type, error_code); |
| 424 if (new_peer) | 442 if (new_peer) |
| 425 request_info->peer = new_peer; | 443 request_info->peer = new_peer; |
| 426 } | 444 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 | 530 |
| 513 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} | 531 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} |
| 514 | 532 |
| 515 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { | 533 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { |
| 516 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message) | 534 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message) |
| 517 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress) | 535 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress) |
| 518 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse) | 536 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse) |
| 519 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, | 537 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, |
| 520 OnReceivedCachedMetadata) | 538 OnReceivedCachedMetadata) |
| 521 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedRedirect, OnReceivedRedirect) | 539 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedRedirect, OnReceivedRedirect) |
| 540 IPC_MESSAGE_HANDLER(ResourceMsg_SetDataBuffer, OnSetDataBuffer) |
| 522 IPC_MESSAGE_HANDLER(ResourceMsg_DataReceived, OnReceivedData) | 541 IPC_MESSAGE_HANDLER(ResourceMsg_DataReceived, OnReceivedData) |
| 523 IPC_MESSAGE_HANDLER(ResourceMsg_DataDownloaded, OnDownloadedData) | 542 IPC_MESSAGE_HANDLER(ResourceMsg_DataDownloaded, OnDownloadedData) |
| 524 IPC_MESSAGE_HANDLER(ResourceMsg_RequestComplete, OnRequestComplete) | 543 IPC_MESSAGE_HANDLER(ResourceMsg_RequestComplete, OnRequestComplete) |
| 525 IPC_END_MESSAGE_MAP() | 544 IPC_END_MESSAGE_MAP() |
| 526 } | 545 } |
| 527 | 546 |
| 528 void ResourceDispatcher::FlushDeferredMessages(int request_id) { | 547 void ResourceDispatcher::FlushDeferredMessages(int request_id) { |
| 529 PendingRequestList::iterator it = pending_requests_.find(request_id); | 548 PendingRequestList::iterator it = pending_requests_.find(request_id); |
| 530 if (it == pending_requests_.end()) // The request could have become invalid. | 549 if (it == pending_requests_.end()) // The request could have become invalid. |
| 531 return; | 550 return; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 } | 640 } |
| 622 | 641 |
| 623 // static | 642 // static |
| 624 bool ResourceDispatcher::IsResourceDispatcherMessage( | 643 bool ResourceDispatcher::IsResourceDispatcherMessage( |
| 625 const IPC::Message& message) { | 644 const IPC::Message& message) { |
| 626 switch (message.type()) { | 645 switch (message.type()) { |
| 627 case ResourceMsg_UploadProgress::ID: | 646 case ResourceMsg_UploadProgress::ID: |
| 628 case ResourceMsg_ReceivedResponse::ID: | 647 case ResourceMsg_ReceivedResponse::ID: |
| 629 case ResourceMsg_ReceivedCachedMetadata::ID: | 648 case ResourceMsg_ReceivedCachedMetadata::ID: |
| 630 case ResourceMsg_ReceivedRedirect::ID: | 649 case ResourceMsg_ReceivedRedirect::ID: |
| 650 case ResourceMsg_SetDataBuffer::ID: |
| 631 case ResourceMsg_DataReceived::ID: | 651 case ResourceMsg_DataReceived::ID: |
| 632 case ResourceMsg_DataDownloaded::ID: | 652 case ResourceMsg_DataDownloaded::ID: |
| 633 case ResourceMsg_RequestComplete::ID: | 653 case ResourceMsg_RequestComplete::ID: |
| 634 return true; | 654 return true; |
| 635 | 655 |
| 636 default: | 656 default: |
| 637 break; | 657 break; |
| 638 } | 658 } |
| 639 | 659 |
| 640 return false; | 660 return false; |
| 641 } | 661 } |
| 642 | 662 |
| 643 // static | 663 // static |
| 644 void ResourceDispatcher::ReleaseResourcesInDataMessage( | 664 void ResourceDispatcher::ReleaseResourcesInDataMessage( |
| 645 const IPC::Message& message) { | 665 const IPC::Message& message) { |
| 646 PickleIterator iter(message); | 666 PickleIterator iter(message); |
| 647 int request_id; | 667 int request_id; |
| 648 if (!message.ReadInt(&iter, &request_id)) { | 668 if (!message.ReadInt(&iter, &request_id)) { |
| 649 NOTREACHED() << "malformed resource message"; | 669 NOTREACHED() << "malformed resource message"; |
| 650 return; | 670 return; |
| 651 } | 671 } |
| 652 | 672 |
| 653 // If the message contains a shared memory handle, we should close the | 673 // If the message contains a shared memory handle, we should close the handle |
| 654 // handle or there will be a memory leak. | 674 // or there will be a memory leak. |
| 655 if (message.type() == ResourceMsg_DataReceived::ID) { | 675 if (message.type() == ResourceMsg_SetDataBuffer::ID) { |
| 656 base::SharedMemoryHandle shm_handle; | 676 base::SharedMemoryHandle shm_handle; |
| 657 if (IPC::ParamTraits<base::SharedMemoryHandle>::Read(&message, | 677 if (IPC::ParamTraits<base::SharedMemoryHandle>::Read(&message, |
| 658 &iter, | 678 &iter, |
| 659 &shm_handle)) { | 679 &shm_handle)) { |
| 660 base::SharedMemory::CloseHandle(shm_handle); | 680 if (base::SharedMemory::IsHandleValid(shm_handle)) |
| 681 base::SharedMemory::CloseHandle(shm_handle); |
| 661 } | 682 } |
| 662 } | 683 } |
| 663 } | 684 } |
| 664 | 685 |
| 665 // static | 686 // static |
| 666 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { | 687 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { |
| 667 while (!queue->empty()) { | 688 while (!queue->empty()) { |
| 668 IPC::Message* message = queue->front(); | 689 IPC::Message* message = queue->front(); |
| 669 ReleaseResourcesInDataMessage(*message); | 690 ReleaseResourcesInDataMessage(*message); |
| 670 queue->pop_front(); | 691 queue->pop_front(); |
| 671 delete message; | 692 delete message; |
| 672 } | 693 } |
| 673 } | 694 } |
| 674 | 695 |
| 675 } // namespace content | 696 } // namespace content |
| OLD | NEW |