| Index: content/browser/blob_storage/blob_dispatcher_host.cc
|
| diff --git a/content/browser/blob_storage/blob_dispatcher_host.cc b/content/browser/blob_storage/blob_dispatcher_host.cc
|
| index 2c43055a5ecf3c7b9ff45cb2269bbfb5910aed77..6c24a15425f9a2943bacd42b12f93b051987b3e1 100644
|
| --- a/content/browser/blob_storage/blob_dispatcher_host.cc
|
| +++ b/content/browser/blob_storage/blob_dispatcher_host.cc
|
| @@ -12,8 +12,8 @@
|
| #include "content/browser/blob_storage/chrome_blob_storage_context.h"
|
| #include "content/common/fileapi/webblob_messages.h"
|
| #include "ipc/ipc_platform_file.h"
|
| +#include "storage/browser/blob/blob_data_handle.h"
|
| #include "storage/browser/blob/blob_storage_context.h"
|
| -#include "storage/browser/blob/blob_transport_result.h"
|
| #include "storage/common/blob_storage/blob_item_bytes_request.h"
|
| #include "storage/common/blob_storage/blob_item_bytes_response.h"
|
| #include "storage/common/data_element.h"
|
| @@ -21,8 +21,7 @@
|
|
|
| using storage::BlobStorageContext;
|
| using storage::BlobStorageRegistry;
|
| -using storage::BlobTransportResult;
|
| -using storage::IPCBlobCreationCancelCode;
|
| +using storage::BlobStatus;
|
|
|
| namespace content {
|
| namespace {
|
| @@ -54,10 +53,9 @@ void BlobDispatcherHost::OnChannelClosing() {
|
| bool BlobDispatcherHost::OnMessageReceived(const IPC::Message& message) {
|
| bool handled = true;
|
| IPC_BEGIN_MESSAGE_MAP(BlobDispatcherHost, message)
|
| - IPC_MESSAGE_HANDLER(BlobStorageMsg_RegisterBlobUUID, OnRegisterBlobUUID)
|
| - IPC_MESSAGE_HANDLER(BlobStorageMsg_StartBuildingBlob, OnStartBuildingBlob)
|
| + IPC_MESSAGE_HANDLER(BlobStorageMsg_RegisterBlob, OnRegisterBlob)
|
| IPC_MESSAGE_HANDLER(BlobStorageMsg_MemoryItemResponse, OnMemoryItemResponse)
|
| - IPC_MESSAGE_HANDLER(BlobStorageMsg_CancelBuildingBlob, OnCancelBuildingBlob)
|
| + IPC_MESSAGE_HANDLER(BlobStorageMsg_SendBlobStatus, OnCancelBuildingBob)
|
| IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementRefCount, OnIncrementBlobRefCount)
|
| IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementRefCount, OnDecrementBlobRefCount)
|
| IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicURL, OnRegisterPublicBlobURL)
|
| @@ -67,11 +65,11 @@ bool BlobDispatcherHost::OnMessageReceived(const IPC::Message& message) {
|
| return handled;
|
| }
|
|
|
| -void BlobDispatcherHost::OnRegisterBlobUUID(
|
| +void BlobDispatcherHost::OnRegisterBlob(
|
| const std::string& uuid,
|
| const std::string& content_type,
|
| const std::string& content_disposition,
|
| - const std::set<std::string>& referenced_blob_uuids) {
|
| + const std::vector<storage::DataElement>& descriptions) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| BlobStorageContext* context = this->context();
|
| if (uuid.empty() || context->registry().HasEntry(uuid) ||
|
| @@ -80,68 +78,13 @@ void BlobDispatcherHost::OnRegisterBlobUUID(
|
| return;
|
| }
|
| blobs_inuse_map_[uuid] = 1;
|
| - BlobTransportResult result = async_builder_.RegisterBlobUUID(
|
| - uuid, content_type, content_disposition, referenced_blob_uuids, context);
|
| - switch (result) {
|
| - case BlobTransportResult::BAD_IPC:
|
| - blobs_inuse_map_.erase(uuid);
|
| - bad_message::ReceivedBadMessage(this,
|
| - bad_message::BDH_CONSTRUCTION_FAILED);
|
| - break;
|
| - case BlobTransportResult::CANCEL_REFERENCED_BLOB_BROKEN:
|
| - // The async builder builds the blob as broken, and we just need to send
|
| - // the cancel message back to the renderer.
|
| - Send(new BlobStorageMsg_CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN));
|
| - break;
|
| - case BlobTransportResult::DONE:
|
| - break;
|
| - case BlobTransportResult::CANCEL_MEMORY_FULL:
|
| - case BlobTransportResult::CANCEL_FILE_ERROR:
|
| - case BlobTransportResult::CANCEL_UNKNOWN:
|
| - case BlobTransportResult::PENDING_RESPONSES:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -}
|
| -
|
| -void BlobDispatcherHost::OnStartBuildingBlob(
|
| - const std::string& uuid,
|
| - const std::vector<storage::DataElement>& descriptions) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| - if (uuid.empty()) {
|
| - SendIPCResponse(uuid, BlobTransportResult::BAD_IPC);
|
| - return;
|
| - }
|
| - BlobStorageContext* context = this->context();
|
| - const BlobStorageRegistry::Entry* entry = context->registry().GetEntry(uuid);
|
| - if (!entry || entry->state == BlobStorageRegistry::BlobState::BROKEN) {
|
| - // We ignore messages for blobs that don't exist to handle the case where
|
| - // the renderer de-refs a blob that we're still constructing, and there are
|
| - // no references to that blob. We ignore broken as well, in the case where
|
| - // we decided to break a blob after RegisterBlobUUID is called.
|
| - // Second, if the last dereference of the blob happened on a different host,
|
| - // then we still haven't gotten rid of the 'building' state in the original
|
| - // host. So we call cancel, and send the message just in case that happens.
|
| - if (async_builder_.IsBeingBuilt(uuid)) {
|
| - async_builder_.CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING,
|
| - context);
|
| - Send(new BlobStorageMsg_CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING));
|
| - }
|
| - return;
|
| - }
|
| - if (!async_builder_.IsBeingBuilt(uuid)) {
|
| - SendIPCResponse(uuid, BlobTransportResult::BAD_IPC);
|
| - return;
|
| - }
|
| - // |this| owns async_builder_ so using base::Unretained(this) is safe.
|
| - BlobTransportResult result = async_builder_.StartBuildingBlob(
|
| - uuid, descriptions, context->memory_available(), context,
|
| + BlobStatus result = async_builder_.RegisterBlob(
|
| + uuid, content_type, content_disposition, descriptions, context,
|
| base::Bind(&BlobDispatcherHost::SendMemoryRequest, base::Unretained(this),
|
| - uuid));
|
| - SendIPCResponse(uuid, result);
|
| + uuid),
|
| + base::Bind(&BlobDispatcherHost::MaybeSendFinalBlobStatus,
|
| + base::Unretained(this), uuid));
|
| + MaybeSendFinalBlobStatus(uuid, result);
|
| }
|
|
|
| void BlobDispatcherHost::OnMemoryItemResponse(
|
| @@ -149,12 +92,12 @@ void BlobDispatcherHost::OnMemoryItemResponse(
|
| const std::vector<storage::BlobItemBytesResponse>& responses) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| if (uuid.empty()) {
|
| - SendIPCResponse(uuid, BlobTransportResult::BAD_IPC);
|
| + bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
|
| return;
|
| }
|
| BlobStorageContext* context = this->context();
|
| const BlobStorageRegistry::Entry* entry = context->registry().GetEntry(uuid);
|
| - if (!entry || entry->state == BlobStorageRegistry::BlobState::BROKEN) {
|
| + if (!entry || BlobStatusIsError(entry->status)) {
|
| // We ignore messages for blobs that don't exist to handle the case where
|
| // the renderer de-refs a blob that we're still constructing, and there are
|
| // no references to that blob. We ignore broken as well, in the case where
|
| @@ -165,33 +108,31 @@ void BlobDispatcherHost::OnMemoryItemResponse(
|
| // host. So we call cancel, and send the message just in case that happens.
|
| if (async_builder_.IsBeingBuilt(uuid)) {
|
| async_builder_.CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING,
|
| - context);
|
| - Send(new BlobStorageMsg_CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING));
|
| + uuid, BlobStatus::BLOB_DEREFERENCED_WHILE_BUILDING, context);
|
| + MaybeSendFinalBlobStatus(uuid,
|
| + BlobStatus::BLOB_DEREFERENCED_WHILE_BUILDING);
|
| }
|
| return;
|
| }
|
| if (!async_builder_.IsBeingBuilt(uuid)) {
|
| - SendIPCResponse(uuid, BlobTransportResult::BAD_IPC);
|
| + bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
|
| return;
|
| }
|
| - BlobTransportResult result =
|
| + BlobStatus result =
|
| async_builder_.OnMemoryResponses(uuid, responses, context);
|
| - SendIPCResponse(uuid, result);
|
| + MaybeSendFinalBlobStatus(uuid, result);
|
| }
|
|
|
| -void BlobDispatcherHost::OnCancelBuildingBlob(
|
| - const std::string& uuid,
|
| - const storage::IPCBlobCreationCancelCode code) {
|
| +void BlobDispatcherHost::OnCancelBuildingBob(const std::string& uuid,
|
| + const storage::BlobStatus code) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| if (uuid.empty()) {
|
| - SendIPCResponse(uuid, BlobTransportResult::BAD_IPC);
|
| + bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
|
| return;
|
| }
|
| BlobStorageContext* context = this->context();
|
| const BlobStorageRegistry::Entry* entry = context->registry().GetEntry(uuid);
|
| - if (!entry || entry->state == BlobStorageRegistry::BlobState::BROKEN) {
|
| + if (!entry || BlobStatusIsError(entry->status)) {
|
| // We ignore messages for blobs that don't exist to handle the case where
|
| // the renderer de-refs a blob that we're still constructing, and there are
|
| // no references to that blob. We ignore broken as well, in the case where
|
| @@ -202,13 +143,13 @@ void BlobDispatcherHost::OnCancelBuildingBlob(
|
| // host. So we call cancel just in case this happens.
|
| if (async_builder_.IsBeingBuilt(uuid)) {
|
| async_builder_.CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING,
|
| - context);
|
| + uuid, BlobStatus::BLOB_DEREFERENCED_WHILE_BUILDING, context);
|
| }
|
| return;
|
| }
|
| - if (!async_builder_.IsBeingBuilt(uuid)) {
|
| - SendIPCResponse(uuid, BlobTransportResult::BAD_IPC);
|
| + // We should only get these messages for errors.
|
| + if (!async_builder_.IsBeingBuilt(uuid) || !storage::BlobStatusIsError(code)) {
|
| + bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
|
| return;
|
| }
|
| VLOG(1) << "Blob construction of " << uuid << " cancelled by renderer. "
|
| @@ -256,10 +197,9 @@ void BlobDispatcherHost::OnDecrementBlobRefCount(const std::string& uuid) {
|
| if (async_builder_.IsBeingBuilt(uuid) &&
|
| !context->registry().HasEntry(uuid)) {
|
| async_builder_.CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING,
|
| - context);
|
| - Send(new BlobStorageMsg_CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING));
|
| + uuid, BlobStatus::BLOB_DEREFERENCED_WHILE_BUILDING, context);
|
| + MaybeSendFinalBlobStatus(uuid,
|
| + BlobStatus::BLOB_DEREFERENCED_WHILE_BUILDING);
|
| }
|
| }
|
| }
|
| @@ -309,42 +249,23 @@ void BlobDispatcherHost::SendMemoryRequest(
|
| std::unique_ptr<std::vector<base::File>> files) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| std::vector<IPC::PlatformFileForTransit> file_handles;
|
| - // TODO(dmurph): Support file-backed blob transportation.
|
| - DCHECK(files->empty());
|
| + for (base::File& file : *files) {
|
| + file_handles.push_back(IPC::TakePlatformFileForTransit(std::move(file)));
|
| + }
|
| Send(new BlobStorageMsg_RequestMemoryItem(uuid, *requests, *memory_handles,
|
| file_handles));
|
| }
|
|
|
| -void BlobDispatcherHost::SendIPCResponse(const std::string& uuid,
|
| - storage::BlobTransportResult result) {
|
| - switch (result) {
|
| - case BlobTransportResult::BAD_IPC:
|
| - bad_message::ReceivedBadMessage(this,
|
| - bad_message::BDH_CONSTRUCTION_FAILED);
|
| - return;
|
| - case BlobTransportResult::CANCEL_MEMORY_FULL:
|
| - Send(new BlobStorageMsg_CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::OUT_OF_MEMORY));
|
| - return;
|
| - case BlobTransportResult::CANCEL_FILE_ERROR:
|
| - Send(new BlobStorageMsg_CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::FILE_WRITE_FAILED));
|
| - return;
|
| - case BlobTransportResult::CANCEL_REFERENCED_BLOB_BROKEN:
|
| - Send(new BlobStorageMsg_CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN));
|
| - return;
|
| - case BlobTransportResult::CANCEL_UNKNOWN:
|
| - Send(new BlobStorageMsg_CancelBuildingBlob(
|
| - uuid, IPCBlobCreationCancelCode::UNKNOWN));
|
| - return;
|
| - case BlobTransportResult::PENDING_RESPONSES:
|
| - return;
|
| - case BlobTransportResult::DONE:
|
| - Send(new BlobStorageMsg_DoneBuildingBlob(uuid));
|
| - return;
|
| +void BlobDispatcherHost::MaybeSendFinalBlobStatus(const std::string& uuid,
|
| + BlobStatus status) {
|
| + if (storage::BlobStatusIsBadIPC(status)) {
|
| + blobs_inuse_map_.erase(uuid);
|
| + bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
|
| + return;
|
| }
|
| - NOTREACHED();
|
| + if (BlobStatusIsPending(status))
|
| + return;
|
| + Send(new BlobStorageMsg_SendBlobStatus(uuid, status));
|
| }
|
|
|
| bool BlobDispatcherHost::IsInUseInHost(const std::string& uuid) {
|
|
|