| Index: content/browser/indexed_db/indexed_db_dispatcher_host.cc
|
| diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
|
| index ec8737b81680e5dd2c39873ee125df951688239f..2d432d90fa513ee60922073106eda39010c5e1ae 100644
|
| --- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc
|
| +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
|
| @@ -7,6 +7,7 @@
|
| #include "base/bind.h"
|
| #include "base/command_line.h"
|
| #include "base/files/file_path.h"
|
| +#include "base/guid.h"
|
| #include "base/memory/scoped_vector.h"
|
| #include "base/process/process.h"
|
| #include "base/stl_util.h"
|
| @@ -69,7 +70,8 @@ IndexedDBDispatcherHost::IndexedDBDispatcherHost(
|
| }
|
|
|
| IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {
|
| - STLDeleteValues(&blob_data_handle_map_);
|
| + for (auto& iter : blob_data_handle_map_)
|
| + delete iter.second.first;
|
| }
|
|
|
| void IndexedDBDispatcherHost::OnChannelConnected(int32 peer_pid) {
|
| @@ -118,10 +120,16 @@ void IndexedDBDispatcherHost::ResetDispatcherHosts() {
|
|
|
| base::TaskRunner* IndexedDBDispatcherHost::OverrideTaskRunnerForMessage(
|
| const IPC::Message& message) {
|
| - if (IPC_MESSAGE_CLASS(message) == IndexedDBMsgStart &&
|
| - message.type() != IndexedDBHostMsg_DatabasePut::ID)
|
| - return indexed_db_context_->TaskRunner();
|
| - return NULL;
|
| + if (IPC_MESSAGE_CLASS(message) != IndexedDBMsgStart)
|
| + return NULL;
|
| +
|
| + switch (message.type()) {
|
| + case IndexedDBHostMsg_DatabasePut::ID:
|
| + case IndexedDBHostMsg_AckReceivedBlobs::ID:
|
| + return NULL;
|
| + default:
|
| + return indexed_db_context_->TaskRunner();
|
| + }
|
| }
|
|
|
| bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message) {
|
| @@ -129,7 +137,8 @@ bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message) {
|
| return false;
|
|
|
| DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread() ||
|
| - message.type() == IndexedDBHostMsg_DatabasePut::ID);
|
| + (message.type() == IndexedDBHostMsg_DatabasePut::ID ||
|
| + message.type() == IndexedDBHostMsg_AckReceivedBlobs::ID));
|
|
|
| bool handled = database_dispatcher_host_->OnMessageReceived(message) ||
|
| cursor_dispatcher_host_->OnMessageReceived(message);
|
| @@ -209,18 +218,44 @@ uint32 IndexedDBDispatcherHost::TransactionIdToProcessId(
|
| return (host_transaction_id >> 32) & 0xffffffff;
|
| }
|
|
|
| -void IndexedDBDispatcherHost::HoldBlobDataHandle(
|
| - const std::string& uuid,
|
| - scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
|
| +std::string IndexedDBDispatcherHost::HoldBlobData(
|
| + const IndexedDBBlobInfo& blob_info) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + std::string uuid = blob_info.uuid();
|
| + storage::BlobStorageContext* context = blob_storage_context_->context();
|
| + scoped_ptr<storage::BlobDataHandle> blob_data_handle;
|
| + if (uuid.empty()) {
|
| + uuid = base::GenerateGUID();
|
| + scoped_refptr<storage::BlobData> blob_data = new storage::BlobData(uuid);
|
| + blob_data->set_content_type(base::UTF16ToUTF8(blob_info.type()));
|
| + blob_data->AppendFile(blob_info.file_path(), 0, blob_info.size(),
|
| + blob_info.last_modified());
|
| + blob_data_handle = context->AddFinishedBlob(blob_data.get());
|
| + } else {
|
| + auto iter = blob_data_handle_map_.find(uuid);
|
| + if (iter != blob_data_handle_map_.end()) {
|
| + iter->second.second += 1;
|
| + return uuid;
|
| + }
|
| + blob_data_handle = context->GetBlobDataFromUUID(uuid);
|
| + }
|
| +
|
| DCHECK(!ContainsKey(blob_data_handle_map_, uuid));
|
| - blob_data_handle_map_[uuid] = blob_data_handle.release();
|
| + blob_data_handle_map_[uuid] = std::make_pair(blob_data_handle.release(), 1);
|
| + return uuid;
|
| }
|
|
|
| -void IndexedDBDispatcherHost::DropBlobDataHandle(const std::string& uuid) {
|
| +void IndexedDBDispatcherHost::DropBlobData(const std::string& uuid) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| BlobDataHandleMap::iterator iter = blob_data_handle_map_.find(uuid);
|
| if (iter != blob_data_handle_map_.end()) {
|
| - delete iter->second;
|
| - blob_data_handle_map_.erase(iter);
|
| + DCHECK_GE(iter->second.second, 1);
|
| + if (iter->second.second == 1) {
|
| + delete iter->second.first;
|
| + blob_data_handle_map_.erase(iter);
|
| + } else {
|
| + iter->second.second -= 1;
|
| + }
|
| } else {
|
| DLOG(FATAL) << "Failed to find blob UUID in map:" << uuid;
|
| }
|
| @@ -342,9 +377,9 @@ void IndexedDBDispatcherHost::OnPutHelper(
|
|
|
| void IndexedDBDispatcherHost::OnAckReceivedBlobs(
|
| const std::vector<std::string>& uuids) {
|
| - DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| for (const auto& uuid : uuids)
|
| - DropBlobDataHandle(uuid);
|
| + DropBlobData(uuid);
|
| }
|
|
|
| void IndexedDBDispatcherHost::FinishTransaction(int64 host_transaction_id,
|
| @@ -453,9 +488,9 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::CloseAll() {
|
|
|
| bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived(
|
| const IPC::Message& message) {
|
| -
|
| DCHECK(
|
| - (message.type() == IndexedDBHostMsg_DatabasePut::ID) ||
|
| + (message.type() == IndexedDBHostMsg_DatabasePut::ID ||
|
| + message.type() == IndexedDBHostMsg_AckReceivedBlobs::ID) ||
|
| parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
|
|
|
| bool handled = true;
|
|
|