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 |