Chromium Code Reviews| Index: content/child/blob_storage/blob_transport_controller.cc |
| diff --git a/content/child/blob_storage/blob_transport_controller.cc b/content/child/blob_storage/blob_transport_controller.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..25865dc18003c69c93c80aed3524e2d96f931fcf |
| --- /dev/null |
| +++ b/content/child/blob_storage/blob_transport_controller.cc |
| @@ -0,0 +1,136 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/child/blob_storage/blob_transport_controller.h" |
| + |
| +#include <vector> |
| + |
| +#include "base/memory/singleton.h" |
| +#include "content/child/blob_storage/blob_consolidation.h" |
| +#include "content/child/thread_safe_sender.h" |
| +#include "content/common/blob_storage/blob_storage_messages.h" |
| +#include "ipc/ipc_sender.h" |
| +#include "storage/common/blob_storage/blob_item_bytes_request.h" |
| +#include "storage/common/blob_storage/blob_item_bytes_response.h" |
| + |
| +namespace content { |
| + |
| +using storage::IPCBlobCreationCancelCode; |
| + |
| +using ConsolidatedItem = BlobConsolidation::ConsolidatedItem; |
| +using ReadStatus = BlobConsolidation::ReadStatus; |
| +using ResponsesStatus = BlobTransportTemporaryHolder::ResponsesStatus; |
| + |
| +const size_t kLargeThresholdBytes = 250 * 1024; |
| + |
| +BlobTransportController* BlobTransportController::GetInstance() { |
| + return Singleton<BlobTransportController>::get(); |
|
michaeln
2015/08/18 02:50:35
Does base::LazyInstance<T>::Leaky work for this? S
dmurph
2015/10/07 00:32:36
Done.
|
| +} |
| + |
| +BlobTransportController::~BlobTransportController() {} |
| + |
| +void BlobTransportController::InitiateBlobTransfer( |
| + const std::string& uuid, |
| + const std::string& type, |
| + scoped_ptr<BlobConsolidation> consolidation, |
| + IPC::Sender* sender) { |
| + holder_.HoldBlobConsolidation(uuid, consolidation.Pass()); |
| + |
| + std::vector<storage::DataElement> descriptions; |
| + holder_.GetDescriptions(uuid, kLargeThresholdBytes, &descriptions); |
| + sender->Send(new BlobStorageMsg_StartBuildingBlob(uuid, type, descriptions)); |
| +} |
| + |
| +void BlobTransportController::OnMemoryRequest( |
| + const std::string& uuid, |
| + const std::vector<storage::BlobItemBytesRequest>& requests, |
| + std::vector<base::SharedMemoryHandle>* memory_handles, |
| + const std::vector<IPC::PlatformFileForTransit>& file_handles, |
| + IPC::Sender* sender) { |
| + std::vector<storage::BlobItemBytesResponse> responses; |
| + ResponsesStatus status = holder_.GetResponses(uuid, requests, memory_handles, |
| + file_handles, &responses); |
| + |
| + bool success = false; |
| + switch (status) { |
| + case ResponsesStatus::BLOB_NOT_FOUND: |
| + LOG(ERROR) << "Unable to find blob " << uuid << "."; |
|
michaeln
2015/08/18 02:50:35
Consider switching these to DVLOG(1). See http://w
dmurph
2015/10/07 00:32:35
Done.
|
| + return; |
| + case ResponsesStatus::INVALID_ITEM_INDEX: |
| + LOG(ERROR) << "Index out of bounds for blob item in blob " << uuid << "."; |
| + break; |
| + case ResponsesStatus::INVALID_DATA_RANGE: |
| + LOG(ERROR) << "Data range out of bounds for blob item in blob " << uuid |
| + << "."; |
| + break; |
| + case ResponsesStatus::INVALID_ITEM: |
| + LOG(ERROR) << "Requesting data from non-memory item in blob " << uuid |
| + << "."; |
| + break; |
| + case ResponsesStatus::INVALID_HANDLE_INDEX: |
| + LOG(ERROR) << "Invalid handle index for transferring in blob " << uuid |
| + << "."; |
| + break; |
| + case ResponsesStatus::SHARED_MEMORY_MAP_FAILED: |
| + // This would happen if the renderer process doesn't have enough memory |
| + // to map the shared memory, which is possible if we don't have much |
| + // memory. If this scenario happens often, we could delay the response |
| + // until we have enough memory. For now we just fail. |
| + LOG(ERROR) << "Unable to map shared memory to send blob " << uuid << "."; |
| + break; |
| + case ResponsesStatus::UNKNOWN: |
| + LOG(ERROR) << "Unknown error while populating data for blob " << uuid |
| + << "."; |
| + break; |
| + case ResponsesStatus::SUCCESS: |
| + success = true; |
| + break; |
| + } |
| + |
| + if (success) { |
| + sender->Send(new BlobStorageMsg_MemoryItemResponse(uuid, responses)); |
| + } else { |
| + LOG(ERROR) << "Canceling blob transfer for blob " << uuid; |
| + CancelBlobTransfer(uuid, IPCBlobCreationCancelCode::UNKNOWN, sender); |
| + } |
| +} |
| + |
| +void BlobTransportController::OnCancel( |
| + const std::string& uuid, |
| + storage::IPCBlobCreationCancelCode code) { |
| + LOG(ERROR) << "Received blob cancel for blob " << uuid << " with reason:"; |
| + switch (code) { |
| + case IPCBlobCreationCancelCode::UNKNOWN: |
| + LOG(ERROR) << "Unknown."; |
| + break; |
| + case IPCBlobCreationCancelCode::OUT_OF_MEMORY: |
| + LOG(ERROR) << "Out of Memory."; |
| + break; |
| + case IPCBlobCreationCancelCode::FILE_WRITE_FAILED: |
| + LOG(ERROR) << "File Write Failed (Invalid cancel reason!)."; |
| + break; |
| + } |
| + holder_.ReleaseBlob(uuid); |
| +} |
| + |
| +void BlobTransportController::OnDone(const std::string& uuid) { |
| + holder_.ReleaseBlob(uuid); |
| +} |
| + |
| +void BlobTransportController::OnChannelClose() { |
| + // TODO(dmurph): When implementing the disk-backed transport, invalidate async |
| + // disk calls so they don't call the sender. |
|
michaeln
2015/08/18 02:50:35
should we clear the map of consolidations here and
dmurph
2015/10/07 00:32:35
Since all of the async versions of the transfers a
|
| +} |
| + |
| +BlobTransportController::BlobTransportController() {} |
| + |
| +void BlobTransportController::CancelBlobTransfer( |
| + const std::string& uuid, |
| + storage::IPCBlobCreationCancelCode code, |
| + IPC::Sender* sender) { |
| + sender->Send(new BlobStorageMsg_CancelBuildingBlob(uuid, code)); |
| + holder_.ReleaseBlob(uuid); |
| +} |
| + |
| +} // namespace content |