summaryrefslogtreecommitdiffstats
path: root/chromium/content/child/indexed_db/indexed_db_dispatcher.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/child/indexed_db/indexed_db_dispatcher.cc')
-rw-r--r--chromium/content/child/indexed_db/indexed_db_dispatcher.cc217
1 files changed, 145 insertions, 72 deletions
diff --git a/chromium/content/child/indexed_db/indexed_db_dispatcher.cc b/chromium/content/child/indexed_db/indexed_db_dispatcher.cc
index 1f242fcd7aa..e814cc87420 100644
--- a/chromium/content/child/indexed_db/indexed_db_dispatcher.cc
+++ b/chromium/content/child/indexed_db/indexed_db_dispatcher.cc
@@ -4,6 +4,8 @@
#include "content/child/indexed_db/indexed_db_dispatcher.h"
+#include <utility>
+
#include "base/format_macros.h"
#include "base/lazy_instance.h"
#include "base/strings/stringprintf.h"
@@ -19,8 +21,10 @@
#include "third_party/WebKit/public/platform/WebIDBDatabaseError.h"
#include "third_party/WebKit/public/platform/WebIDBDatabaseException.h"
+using blink::WebBlobInfo;
using blink::WebData;
using blink::WebIDBCallbacks;
+using blink::WebIDBCursor;
using blink::WebIDBDatabase;
using blink::WebIDBDatabaseCallbacks;
using blink::WebIDBDatabaseError;
@@ -29,7 +33,6 @@ using blink::WebIDBMetadata;
using blink::WebString;
using blink::WebVector;
using base::ThreadLocalPointer;
-using webkit_glue::WorkerTaskRunner;
namespace content {
static base::LazyInstance<ThreadLocalPointer<IndexedDBDispatcher> >::Leaky
@@ -42,7 +45,9 @@ IndexedDBDispatcher* const kHasBeenDeleted =
} // unnamed namespace
-const size_t kMaxIDBValueSizeInBytes = 64 * 1024 * 1024;
+const size_t kMaxIDBMessageOverhead = 1024 * 1024; // 1MB; arbitrarily chosen.
+const size_t kMaxIDBValueSizeInBytes =
+ IPC::Channel::kMaximumMessageSize - kMaxIDBMessageOverhead;
IndexedDBDispatcher::IndexedDBDispatcher(ThreadSafeSender* thread_safe_sender)
: thread_safe_sender_(thread_safe_sender) {
@@ -72,7 +77,7 @@ IndexedDBDispatcher* IndexedDBDispatcher::ThreadSpecificInstance(
IndexedDBDispatcher* dispatcher = new IndexedDBDispatcher(thread_safe_sender);
if (WorkerTaskRunner::Instance()->CurrentWorkerId())
- webkit_glue::WorkerTaskRunner::Instance()->AddStopObserver(dispatcher);
+ WorkerTaskRunner::Instance()->AddStopObserver(dispatcher);
return dispatcher;
}
@@ -168,9 +173,10 @@ bool IndexedDBDispatcher::Send(IPC::Message* msg) {
void IndexedDBDispatcher::RequestIDBCursorAdvance(
unsigned long count,
WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id) {
+ int32 ipc_cursor_id,
+ int64 transaction_id) {
// Reset all cursor prefetch caches except for this cursor.
- ResetCursorPrefetchCaches(ipc_cursor_id);
+ ResetCursorPrefetchCaches(transaction_id, ipc_cursor_id);
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
@@ -183,9 +189,10 @@ void IndexedDBDispatcher::RequestIDBCursorContinue(
const IndexedDBKey& key,
const IndexedDBKey& primary_key,
WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id) {
+ int32 ipc_cursor_id,
+ int64 transaction_id) {
// Reset all cursor prefetch caches except for this cursor.
- ResetCursorPrefetchCaches(ipc_cursor_id);
+ ResetCursorPrefetchCaches(transaction_id, ipc_cursor_id);
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
@@ -219,7 +226,6 @@ void IndexedDBDispatcher::RequestIDBFactoryOpen(
WebIDBCallbacks* callbacks_ptr,
WebIDBDatabaseCallbacks* database_callbacks_ptr,
const std::string& database_identifier) {
- ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
scoped_ptr<WebIDBDatabaseCallbacks> database_callbacks(
database_callbacks_ptr);
@@ -239,7 +245,6 @@ void IndexedDBDispatcher::RequestIDBFactoryOpen(
void IndexedDBDispatcher::RequestIDBFactoryGetDatabaseNames(
WebIDBCallbacks* callbacks_ptr,
const std::string& database_identifier) {
- ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
IndexedDBHostMsg_FactoryGetDatabaseNames_Params params;
@@ -253,7 +258,6 @@ void IndexedDBDispatcher::RequestIDBFactoryDeleteDatabase(
const base::string16& name,
WebIDBCallbacks* callbacks_ptr,
const std::string& database_identifier) {
- ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
IndexedDBHostMsg_FactoryDeleteDatabase_Params params;
@@ -267,7 +271,6 @@ void IndexedDBDispatcher::RequestIDBFactoryDeleteDatabase(
void IndexedDBDispatcher::RequestIDBDatabaseClose(
int32 ipc_database_id,
int32 ipc_database_callbacks_id) {
- ResetCursorPrefetchCaches();
Send(new IndexedDBHostMsg_DatabaseClose(ipc_database_id));
// There won't be pending database callbacks if the transaction was aborted in
// the initial upgradeneeded event handler.
@@ -280,7 +283,7 @@ void IndexedDBDispatcher::RequestIDBDatabaseCreateTransaction(
int64 transaction_id,
WebIDBDatabaseCallbacks* database_callbacks_ptr,
WebVector<long long> object_store_ids,
- unsigned short mode) {
+ WebIDBDatabase::TransactionMode mode) {
scoped_ptr<WebIDBDatabaseCallbacks> database_callbacks(
database_callbacks_ptr);
IndexedDBHostMsg_DatabaseCreateTransaction_Params params;
@@ -305,9 +308,9 @@ void IndexedDBDispatcher::RequestIDBDatabaseGet(
const IndexedDBKeyRange& key_range,
bool key_only,
WebIDBCallbacks* callbacks) {
- ResetCursorPrefetchCaches();
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
IndexedDBHostMsg_DatabaseGet_Params params;
- init_params(params, callbacks);
+ init_params(&params, callbacks);
params.ipc_database_id = ipc_database_id;
params.transaction_id = transaction_id;
params.object_store_id = object_store_id;
@@ -322,13 +325,14 @@ void IndexedDBDispatcher::RequestIDBDatabasePut(
int64 transaction_id,
int64 object_store_id,
const WebData& value,
+ const blink::WebVector<WebBlobInfo>& web_blob_info,
const IndexedDBKey& key,
WebIDBDatabase::PutMode put_mode,
WebIDBCallbacks* callbacks,
const WebVector<long long>& index_ids,
const WebVector<WebVector<WebIDBKey> >& index_keys) {
- if (value.size() > kMaxIDBValueSizeInBytes) {
+ if (value.size() + key.size_estimate() > kMaxIDBValueSizeInBytes) {
callbacks->onError(WebIDBDatabaseError(
blink::WebIDBDatabaseExceptionUnknownError,
WebString::fromUTF8(base::StringPrintf(
@@ -339,9 +343,9 @@ void IndexedDBDispatcher::RequestIDBDatabasePut(
return;
}
- ResetCursorPrefetchCaches();
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
IndexedDBHostMsg_DatabasePut_Params params;
- init_params(params, callbacks);
+ init_params(&params, callbacks);
params.ipc_database_id = ipc_database_id;
params.transaction_id = transaction_id;
params.object_store_id = object_store_id;
@@ -350,19 +354,34 @@ void IndexedDBDispatcher::RequestIDBDatabasePut(
params.key = key;
params.put_mode = put_mode;
- COMPILE_ASSERT(sizeof(params.index_ids[0]) == sizeof(index_ids[0]),
- Cant_copy);
- params.index_ids
- .assign(index_ids.data(), index_ids.data() + index_ids.size());
-
- params.index_keys.resize(index_keys.size());
- for (size_t i = 0; i < index_keys.size(); ++i) {
- params.index_keys[i].resize(index_keys[i].size());
+ DCHECK_EQ(index_ids.size(), index_keys.size());
+ params.index_keys.resize(index_ids.size());
+ for (size_t i = 0, len = index_ids.size(); i < len; ++i) {
+ params.index_keys[i].first = index_ids[i];
+ params.index_keys[i].second.resize(index_keys[i].size());
for (size_t j = 0; j < index_keys[i].size(); ++j) {
- params.index_keys[i][j] =
+ params.index_keys[i].second[j] =
IndexedDBKey(IndexedDBKeyBuilder::Build(index_keys[i][j]));
}
}
+
+ params.blob_or_file_info.resize(web_blob_info.size());
+ for (size_t i = 0; i < web_blob_info.size(); ++i) {
+ const WebBlobInfo& info = web_blob_info[i];
+ IndexedDBMsg_BlobOrFileInfo& blob_or_file_info =
+ params.blob_or_file_info[i];
+ blob_or_file_info.is_file = info.isFile();
+ if (info.isFile()) {
+ blob_or_file_info.file_path = info.filePath();
+ blob_or_file_info.file_name = info.fileName();
+ blob_or_file_info.last_modified = info.lastModified();
+ }
+ blob_or_file_info.size = info.size();
+ blob_or_file_info.uuid = info.uuid().latin1();
+ DCHECK(blob_or_file_info.uuid.size());
+ blob_or_file_info.mime_type = info.type();
+ }
+
Send(new IndexedDBHostMsg_DatabasePut(params));
}
@@ -372,13 +391,13 @@ void IndexedDBDispatcher::RequestIDBDatabaseOpenCursor(
int64 object_store_id,
int64 index_id,
const IndexedDBKeyRange& key_range,
- unsigned short direction,
+ WebIDBCursor::Direction direction,
bool key_only,
WebIDBDatabase::TaskType task_type,
WebIDBCallbacks* callbacks) {
- ResetCursorPrefetchCaches();
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
IndexedDBHostMsg_DatabaseOpenCursor_Params params;
- init_params(params, callbacks);
+ init_params(&params, callbacks);
params.ipc_database_id = ipc_database_id;
params.transaction_id = transaction_id;
params.object_store_id = object_store_id;
@@ -388,6 +407,10 @@ void IndexedDBDispatcher::RequestIDBDatabaseOpenCursor(
params.key_only = key_only;
params.task_type = task_type;
Send(new IndexedDBHostMsg_DatabaseOpenCursor(params));
+
+ DCHECK(cursor_transaction_ids_.find(params.ipc_callbacks_id) ==
+ cursor_transaction_ids_.end());
+ cursor_transaction_ids_[params.ipc_callbacks_id] = transaction_id;
}
void IndexedDBDispatcher::RequestIDBDatabaseCount(
@@ -397,9 +420,9 @@ void IndexedDBDispatcher::RequestIDBDatabaseCount(
int64 index_id,
const IndexedDBKeyRange& key_range,
WebIDBCallbacks* callbacks) {
- ResetCursorPrefetchCaches();
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
IndexedDBHostMsg_DatabaseCount_Params params;
- init_params(params, callbacks);
+ init_params(&params, callbacks);
params.ipc_database_id = ipc_database_id;
params.transaction_id = transaction_id;
params.object_store_id = object_store_id;
@@ -414,9 +437,9 @@ void IndexedDBDispatcher::RequestIDBDatabaseDeleteRange(
int64 object_store_id,
const IndexedDBKeyRange& key_range,
WebIDBCallbacks* callbacks) {
- ResetCursorPrefetchCaches();
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
IndexedDBHostMsg_DatabaseDeleteRange_Params params;
- init_params(params, callbacks);
+ init_params(&params, callbacks);
params.ipc_database_id = ipc_database_id;
params.transaction_id = transaction_id;
params.object_store_id = object_store_id;
@@ -429,6 +452,7 @@ void IndexedDBDispatcher::RequestIDBDatabaseClear(
int64 transaction_id,
int64 object_store_id,
WebIDBCallbacks* callbacks_ptr) {
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 ipc_callbacks_id = pending_callbacks_.Add(callbacks.release());
Send(new IndexedDBHostMsg_DatabaseClear(CurrentWorkerId(),
@@ -496,37 +520,66 @@ void IndexedDBDispatcher::OnSuccessStringList(
pending_callbacks_.Remove(ipc_callbacks_id);
}
-void IndexedDBDispatcher::OnSuccessValue(int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- const std::string& value) {
- DCHECK_EQ(ipc_thread_id, CurrentWorkerId());
- WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
+static void PrepareWebValueAndBlobInfo(
+ const std::string& value,
+ const std::vector<IndexedDBMsg_BlobOrFileInfo>& blob_info,
+ WebData* web_value,
+ blink::WebVector<WebBlobInfo>* web_blob_info) {
+
+ if (value.empty())
+ return;
+
+ web_value->assign(&*value.begin(), value.size());
+ blink::WebVector<WebBlobInfo> local_blob_info(blob_info.size());
+ for (size_t i = 0; i < blob_info.size(); ++i) {
+ const IndexedDBMsg_BlobOrFileInfo& info = blob_info[i];
+ if (info.is_file) {
+ local_blob_info[i] = WebBlobInfo(WebString::fromUTF8(info.uuid.c_str()),
+ info.file_path,
+ info.file_name,
+ info.mime_type,
+ info.last_modified,
+ info.size);
+ } else {
+ local_blob_info[i] = WebBlobInfo(
+ WebString::fromUTF8(info.uuid.c_str()), info.mime_type, info.size);
+ }
+ }
+ web_blob_info->swap(local_blob_info);
+}
+
+void IndexedDBDispatcher::OnSuccessValue(
+ const IndexedDBMsg_CallbacksSuccessValue_Params& params) {
+ DCHECK_EQ(params.ipc_thread_id, CurrentWorkerId());
+ WebIDBCallbacks* callbacks =
+ pending_callbacks_.Lookup(params.ipc_callbacks_id);
if (!callbacks)
return;
WebData web_value;
- if (value.size())
- web_value.assign(&*value.begin(), value.size());
- callbacks->onSuccess(web_value);
- pending_callbacks_.Remove(ipc_callbacks_id);
+ WebVector<WebBlobInfo> web_blob_info;
+ PrepareWebValueAndBlobInfo(
+ params.value, params.blob_or_file_info, &web_value, &web_blob_info);
+ callbacks->onSuccess(web_value, web_blob_info);
+ pending_callbacks_.Remove(params.ipc_callbacks_id);
+ cursor_transaction_ids_.erase(params.ipc_callbacks_id);
}
void IndexedDBDispatcher::OnSuccessValueWithKey(
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- const std::string& value,
- const IndexedDBKey& primary_key,
- const IndexedDBKeyPath& key_path) {
- DCHECK_EQ(ipc_thread_id, CurrentWorkerId());
- WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
+ const IndexedDBMsg_CallbacksSuccessValueWithKey_Params& params) {
+ DCHECK_EQ(params.ipc_thread_id, CurrentWorkerId());
+ WebIDBCallbacks* callbacks =
+ pending_callbacks_.Lookup(params.ipc_callbacks_id);
if (!callbacks)
return;
WebData web_value;
- if (value.size())
- web_value.assign(&*value.begin(), value.size());
+ WebVector<WebBlobInfo> web_blob_info;
+ PrepareWebValueAndBlobInfo(
+ params.value, params.blob_or_file_info, &web_value, &web_blob_info);
callbacks->onSuccess(web_value,
- WebIDBKeyBuilder::Build(primary_key),
- WebIDBKeyPathBuilder::Build(key_path));
- pending_callbacks_.Remove(ipc_callbacks_id);
+ web_blob_info,
+ WebIDBKeyBuilder::Build(params.primary_key),
+ WebIDBKeyPathBuilder::Build(params.key_path));
+ pending_callbacks_.Remove(params.ipc_callbacks_id);
}
void IndexedDBDispatcher::OnSuccessInteger(int32 ipc_thread_id,
@@ -558,18 +611,27 @@ void IndexedDBDispatcher::OnSuccessOpenCursor(
const IndexedDBKey& key = p.key;
const IndexedDBKey& primary_key = p.primary_key;
WebData web_value;
- if (p.value.size())
- web_value.assign(&*p.value.begin(), p.value.size());
+ WebVector<WebBlobInfo> web_blob_info;
+ PrepareWebValueAndBlobInfo(
+ p.value, p.blob_or_file_info, &web_value, &web_blob_info);
+
+ DCHECK(cursor_transaction_ids_.find(ipc_callbacks_id) !=
+ cursor_transaction_ids_.end());
+ int64 transaction_id = cursor_transaction_ids_[ipc_callbacks_id];
+ cursor_transaction_ids_.erase(ipc_callbacks_id);
WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
if (!callbacks)
return;
- WebIDBCursorImpl* cursor =
- new WebIDBCursorImpl(ipc_object_id, thread_safe_sender_.get());
+ WebIDBCursorImpl* cursor = new WebIDBCursorImpl(
+ ipc_object_id, transaction_id, thread_safe_sender_.get());
cursors_[ipc_object_id] = cursor;
- callbacks->onSuccess(cursor, WebIDBKeyBuilder::Build(key),
- WebIDBKeyBuilder::Build(primary_key), web_value);
+ callbacks->onSuccess(cursor,
+ WebIDBKeyBuilder::Build(key),
+ WebIDBKeyBuilder::Build(primary_key),
+ web_value,
+ web_blob_info);
pending_callbacks_.Remove(ipc_callbacks_id);
}
@@ -583,18 +645,21 @@ void IndexedDBDispatcher::OnSuccessCursorContinue(
const IndexedDBKey& primary_key = p.primary_key;
const std::string& value = p.value;
- WebIDBCursorImpl* cursor = cursors_[ipc_cursor_id];
- DCHECK(cursor);
+ if (cursors_.find(ipc_cursor_id) == cursors_.end())
+ return;
WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
if (!callbacks)
return;
WebData web_value;
- if (value.size())
- web_value.assign(&*value.begin(), value.size());
+ WebVector<WebBlobInfo> web_blob_info;
+ PrepareWebValueAndBlobInfo(
+ value, p.blob_or_file_info, &web_value, &web_blob_info);
callbacks->onSuccess(WebIDBKeyBuilder::Build(key),
- WebIDBKeyBuilder::Build(primary_key), web_value);
+ WebIDBKeyBuilder::Build(primary_key),
+ web_value,
+ web_blob_info);
pending_callbacks_.Remove(ipc_callbacks_id);
}
@@ -607,17 +672,22 @@ void IndexedDBDispatcher::OnSuccessCursorPrefetch(
const std::vector<IndexedDBKey>& keys = p.keys;
const std::vector<IndexedDBKey>& primary_keys = p.primary_keys;
std::vector<WebData> values(p.values.size());
+ DCHECK_EQ(p.values.size(), p.blob_or_file_infos.size());
+ std::vector<WebVector<WebBlobInfo> > blob_infos(p.blob_or_file_infos.size());
for (size_t i = 0; i < p.values.size(); ++i) {
- if (p.values[i].size())
- values[i].assign(&*p.values[i].begin(), p.values[i].size());
+ PrepareWebValueAndBlobInfo(
+ p.values[i], p.blob_or_file_infos[i], &values[i], &blob_infos[i]);
}
- WebIDBCursorImpl* cursor = cursors_[ipc_cursor_id];
- DCHECK(cursor);
- cursor->SetPrefetchData(keys, primary_keys, values);
+ std::map<int32, WebIDBCursorImpl*>::const_iterator cur_iter =
+ cursors_.find(ipc_cursor_id);
+ if (cur_iter == cursors_.end())
+ return;
+
+ cur_iter->second->SetPrefetchData(keys, primary_keys, values, blob_infos);
WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
DCHECK(callbacks);
- cursor->CachedContinue(callbacks);
+ cur_iter->second->CachedContinue(callbacks);
pending_callbacks_.Remove(ipc_callbacks_id);
}
@@ -662,6 +732,7 @@ void IndexedDBDispatcher::OnError(int32 ipc_thread_id,
else
callbacks->onError(WebIDBDatabaseError(code, message));
pending_callbacks_.Remove(ipc_callbacks_id);
+ cursor_transaction_ids_.erase(ipc_callbacks_id);
}
void IndexedDBDispatcher::OnAbort(int32 ipc_thread_id,
@@ -716,10 +787,12 @@ void IndexedDBDispatcher::OnIntVersionChange(int32 ipc_thread_id,
}
void IndexedDBDispatcher::ResetCursorPrefetchCaches(
+ int64 transaction_id,
int32 ipc_exception_cursor_id) {
typedef std::map<int32, WebIDBCursorImpl*>::iterator Iterator;
for (Iterator i = cursors_.begin(); i != cursors_.end(); ++i) {
- if (i->first == ipc_exception_cursor_id)
+ if (i->first == ipc_exception_cursor_id ||
+ i->second->transaction_id() != transaction_id)
continue;
i->second->ResetPrefetchCache();
}