summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsbell@chromium.org <jsbell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-22 08:57:41 +0000
committerjsbell@chromium.org <jsbell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-22 08:57:41 +0000
commit745c743ccb88a0a1eefb0bca0dbaa839f4795307 (patch)
tree35d5a75a1e69ec520c215e7ad5ecf7d98780046d
parent71c8bc7885aeff2bb6f343b3d119f9ce5e9d489f (diff)
downloadchromium_src-745c743ccb88a0a1eefb0bca0dbaa839f4795307.zip
chromium_src-745c743ccb88a0a1eefb0bca0dbaa839f4795307.tar.gz
chromium_src-745c743ccb88a0a1eefb0bca0dbaa839f4795307.tar.bz2
IndexedDB: Only reset prefetch caches for cursors in same transaction
Correct prefetching is predicated on resetting the cache when other requests come in that could invalidate it (i.e. writes) or result in requests processing out of order (i.e. everything). When prefetching was originally implemented, the IDB implementation only handled one transaction at a time, so resetting was done with a big hammer - reset all of a front-end's caches when any other request is made. This was acknowledged as future work during code review. The future is now! Only reset caches for cursors from the same transaction as the triggering request, which should be a performance win for concurrent transactions in the same front-end. BUG=329950 Review URL: https://codereview.chromium.org/128713006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@246245 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/child/indexed_db/indexed_db_dispatcher.cc42
-rw-r--r--content/child/indexed_db/indexed_db_dispatcher.h22
-rw-r--r--content/child/indexed_db/indexed_db_dispatcher_unittest.cc246
-rw-r--r--content/child/indexed_db/webidbcursor_impl.cc7
-rw-r--r--content/child/indexed_db/webidbcursor_impl.h15
-rw-r--r--content/child/indexed_db/webidbcursor_impl_unittest.cc12
-rw-r--r--content/child/thread_safe_sender.h2
-rw-r--r--content/common/indexed_db/indexed_db_messages.h2
8 files changed, 310 insertions, 38 deletions
diff --git a/content/child/indexed_db/indexed_db_dispatcher.cc b/content/child/indexed_db/indexed_db_dispatcher.cc
index 1903ac6..2c72bef 100644
--- a/content/child/indexed_db/indexed_db_dispatcher.cc
+++ b/content/child/indexed_db/indexed_db_dispatcher.cc
@@ -170,9 +170,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);
@@ -185,9 +186,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);
@@ -303,7 +305,7 @@ 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);
params.ipc_database_id = ipc_database_id;
@@ -337,7 +339,7 @@ void IndexedDBDispatcher::RequestIDBDatabasePut(
return;
}
- ResetCursorPrefetchCaches();
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
IndexedDBHostMsg_DatabasePut_Params params;
init_params(params, callbacks);
params.ipc_database_id = ipc_database_id;
@@ -372,7 +374,7 @@ void IndexedDBDispatcher::RequestIDBDatabaseOpenCursor(
bool key_only,
WebIDBDatabase::TaskType task_type,
WebIDBCallbacks* callbacks) {
- ResetCursorPrefetchCaches();
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
IndexedDBHostMsg_DatabaseOpenCursor_Params params;
init_params(params, callbacks);
params.ipc_database_id = ipc_database_id;
@@ -384,6 +386,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(
@@ -393,7 +399,7 @@ 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);
params.ipc_database_id = ipc_database_id;
@@ -410,7 +416,7 @@ 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);
params.ipc_database_id = ipc_database_id;
@@ -425,7 +431,7 @@ void IndexedDBDispatcher::RequestIDBDatabaseClear(
int64 transaction_id,
int64 object_store_id,
WebIDBCallbacks* callbacks_ptr) {
- ResetCursorPrefetchCaches();
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 ipc_callbacks_id = pending_callbacks_.Add(callbacks.release());
Send(new IndexedDBHostMsg_DatabaseClear(CurrentWorkerId(),
@@ -505,6 +511,7 @@ void IndexedDBDispatcher::OnSuccessValue(int32 ipc_thread_id,
web_value.assign(&*value.begin(), value.size());
callbacks->onSuccess(web_value);
pending_callbacks_.Remove(ipc_callbacks_id);
+ cursor_transaction_ids_.erase(ipc_callbacks_id);
}
void IndexedDBDispatcher::OnSuccessValueWithKey(
@@ -558,12 +565,17 @@ void IndexedDBDispatcher::OnSuccessOpenCursor(
if (p.value.size())
web_value.assign(&*p.value.begin(), p.value.size());
+ 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);
@@ -659,6 +671,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,
@@ -713,11 +726,12 @@ void IndexedDBDispatcher::OnIntVersionChange(int32 ipc_thread_id,
}
void IndexedDBDispatcher::ResetCursorPrefetchCaches(
+ int64 transaction_id,
int32 ipc_exception_cursor_id) {
- // TODO(jsbell): Only reset cursors from the same transaction.
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();
}
diff --git a/content/child/indexed_db/indexed_db_dispatcher.h b/content/child/indexed_db/indexed_db_dispatcher.h
index 564bcd7..e15cdd1 100644
--- a/content/child/indexed_db/indexed_db_dispatcher.h
+++ b/content/child/indexed_db/indexed_db_dispatcher.h
@@ -64,7 +64,9 @@ class CONTENT_EXPORT IndexedDBDispatcher
const IndexedDBDatabaseMetadata& idb_metadata);
void OnMessageReceived(const IPC::Message& msg);
- bool Send(IPC::Message* msg);
+
+ // This method is virtual so it can be overridden in unit tests.
+ virtual bool Send(IPC::Message* msg);
void RequestIDBFactoryGetDatabaseNames(
blink::WebIDBCallbacks* callbacks,
@@ -85,13 +87,15 @@ class CONTENT_EXPORT IndexedDBDispatcher
// This method is virtual so it can be overridden in unit tests.
virtual void RequestIDBCursorAdvance(unsigned long count,
blink::WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id);
+ int32 ipc_cursor_id,
+ int64 transaction_id);
// This method is virtual so it can be overridden in unit tests.
virtual void RequestIDBCursorContinue(const IndexedDBKey& key,
const IndexedDBKey& primary_key,
blink::WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id);
+ int32 ipc_cursor_id,
+ int64 transaction_id);
// This method is virtual so it can be overridden in unit tests.
virtual void RequestIDBCursorPrefetch(int n,
@@ -165,8 +169,12 @@ class CONTENT_EXPORT IndexedDBDispatcher
void DatabaseDestroyed(int32 ipc_database_id);
private:
+ FRIEND_TEST_ALL_PREFIXES(IndexedDBDispatcherTest, CursorReset);
+ FRIEND_TEST_ALL_PREFIXES(IndexedDBDispatcherTest, CursorTransactionId);
FRIEND_TEST_ALL_PREFIXES(IndexedDBDispatcherTest, ValueSizeTest);
+ enum { kAllCursors = -1 };
+
static int32 CurrentWorkerId() {
return webkit_glue::WorkerTaskRunner::Instance()->CurrentWorkerId();
}
@@ -232,7 +240,8 @@ class CONTENT_EXPORT IndexedDBDispatcher
int64 new_version);
// Reset cursor prefetch caches for all cursors except exception_cursor_id.
- void ResetCursorPrefetchCaches(int32 ipc_exception_cursor_id = -1);
+ void ResetCursorPrefetchCaches(int64 transaction_id,
+ int32 ipc_exception_cursor_id);
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
@@ -242,6 +251,11 @@ class CONTENT_EXPORT IndexedDBDispatcher
IDMap<blink::WebIDBDatabaseCallbacks, IDMapOwnPointer>
pending_database_callbacks_;
+ // Maps the ipc_callback_id from an open cursor request to the request's
+ // transaction_id. Used to assign the transaction_id to the WebIDBCursorImpl
+ // when it is created.
+ std::map<int32, int64> cursor_transaction_ids_;
+
// Map from cursor id to WebIDBCursorImpl.
std::map<int32, WebIDBCursorImpl*> cursors_;
diff --git a/content/child/indexed_db/indexed_db_dispatcher_unittest.cc b/content/child/indexed_db/indexed_db_dispatcher_unittest.cc
index 61f3b0e..dd4ff12 100644
--- a/content/child/indexed_db/indexed_db_dispatcher_unittest.cc
+++ b/content/child/indexed_db/indexed_db_dispatcher_unittest.cc
@@ -6,8 +6,11 @@
#include "base/message_loop/message_loop_proxy.h"
#include "base/values.h"
#include "content/child/indexed_db/indexed_db_dispatcher.h"
+#include "content/child/indexed_db/webidbcursor_impl.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/indexed_db/indexed_db_key.h"
+#include "content/common/indexed_db/indexed_db_key_range.h"
+#include "content/common/indexed_db/indexed_db_messages.h"
#include "ipc/ipc_sync_message_filter.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebData.h"
@@ -15,6 +18,7 @@
using blink::WebData;
using blink::WebIDBCallbacks;
+using blink::WebIDBCursor;
using blink::WebIDBDatabase;
using blink::WebIDBDatabaseError;
using blink::WebIDBKey;
@@ -27,9 +31,7 @@ class MockCallbacks : public WebIDBCallbacks {
public:
MockCallbacks() : error_seen_(false) {}
- virtual void onError(const WebIDBDatabaseError&) OVERRIDE {
- error_seen_ = true;
- }
+ virtual void onError(const WebIDBDatabaseError&) { error_seen_ = true; }
bool error_seen() const { return error_seen_; }
@@ -37,24 +39,41 @@ class MockCallbacks : public WebIDBCallbacks {
bool error_seen_;
};
+class MockDispatcher : public IndexedDBDispatcher {
+ public:
+ MockDispatcher(ThreadSafeSender* sender) : IndexedDBDispatcher(sender) {}
+
+ virtual bool Send(IPC::Message* msg) OVERRIDE { return true; }
+};
+
} // namespace
-TEST(IndexedDBDispatcherTest, ValueSizeTest) {
+class IndexedDBDispatcherTest : public testing::Test {
+ public:
+ IndexedDBDispatcherTest()
+ : message_loop_proxy_(base::MessageLoopProxy::current()),
+ sync_message_filter_(new IPC::SyncMessageFilter(NULL)),
+ thread_safe_sender_(new ThreadSafeSender(message_loop_proxy_.get(),
+ sync_message_filter_.get())) {}
+
+ protected:
+ scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
+ scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_;
+ scoped_refptr<ThreadSafeSender> thread_safe_sender_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IndexedDBDispatcherTest);
+};
+
+TEST_F(IndexedDBDispatcherTest, ValueSizeTest) {
const std::vector<char> data(kMaxIDBValueSizeInBytes + 1);
const WebData value(&data.front(), data.size());
const int32 ipc_dummy_id = -1;
const int64 transaction_id = 1;
const int64 object_store_id = 2;
- scoped_refptr<base::MessageLoopProxy> message_loop_proxy(
- base::MessageLoopProxy::current());
- scoped_refptr<IPC::SyncMessageFilter> sync_message_filter(
- new IPC::SyncMessageFilter(NULL));
- scoped_refptr<ThreadSafeSender> thread_safe_sender(new ThreadSafeSender(
- message_loop_proxy.get(), sync_message_filter.get()));
-
MockCallbacks callbacks;
- IndexedDBDispatcher dispatcher(thread_safe_sender.get());
+ IndexedDBDispatcher dispatcher(thread_safe_sender_.get());
IndexedDBKey key(0, blink::WebIDBKeyTypeNumber);
dispatcher.RequestIDBDatabasePut(ipc_dummy_id,
transaction_id,
@@ -69,4 +88,207 @@ TEST(IndexedDBDispatcherTest, ValueSizeTest) {
EXPECT_TRUE(callbacks.error_seen());
}
+namespace {
+
+class CursorCallbacks : public WebIDBCallbacks {
+ public:
+ CursorCallbacks(scoped_ptr<WebIDBCursor>* cursor) : cursor_(cursor) {}
+
+ virtual void onSuccess(const WebData&) {}
+ virtual void onSuccess(WebIDBCursor* cursor,
+ const WebIDBKey& key,
+ const WebIDBKey& primaryKey,
+ const WebData& value) {
+ cursor_->reset(cursor);
+ }
+
+ private:
+ scoped_ptr<WebIDBCursor>* cursor_;
+};
+
+} // namespace
+
+TEST_F(IndexedDBDispatcherTest, CursorTransactionId) {
+ const int32 ipc_database_id = -1;
+ const int64 transaction_id = 1234;
+ const int64 object_store_id = 2;
+ const int32 index_id = 3;
+ const unsigned short direction = 0;
+ const bool key_only = false;
+
+ MockDispatcher dispatcher(thread_safe_sender_.get());
+
+ // First case: successful cursor open.
+ {
+ scoped_ptr<WebIDBCursor> cursor;
+ EXPECT_EQ(0UL, dispatcher.cursor_transaction_ids_.size());
+
+ // Make a cursor request. This should record the transaction id.
+ dispatcher.RequestIDBDatabaseOpenCursor(ipc_database_id,
+ transaction_id,
+ object_store_id,
+ index_id,
+ IndexedDBKeyRange(),
+ direction,
+ key_only,
+ blink::WebIDBDatabase::NormalTask,
+ new CursorCallbacks(&cursor));
+
+ // Verify that the transaction id was captured.
+ EXPECT_EQ(1UL, dispatcher.cursor_transaction_ids_.size());
+ EXPECT_FALSE(cursor.get());
+
+ int32 ipc_callbacks_id = dispatcher.cursor_transaction_ids_.begin()->first;
+
+ IndexedDBMsg_CallbacksSuccessIDBCursor_Params params;
+ params.ipc_thread_id = dispatcher.CurrentWorkerId();
+ params.ipc_callbacks_id = ipc_callbacks_id;
+
+ // Now simululate the cursor response.
+ params.ipc_cursor_id = WebIDBCursorImpl::kInvalidCursorId;
+ dispatcher.OnSuccessOpenCursor(params);
+
+ EXPECT_EQ(0UL, dispatcher.cursor_transaction_ids_.size());
+
+ EXPECT_TRUE(cursor.get());
+
+ WebIDBCursorImpl* impl = static_cast<WebIDBCursorImpl*>(cursor.get());
+
+ // This is the primary expectation of this test: the transaction id was
+ // applied to the cursor.
+ EXPECT_EQ(transaction_id, impl->transaction_id());
+ }
+
+ // Second case: null cursor (no data in range)
+ {
+ scoped_ptr<WebIDBCursor> cursor;
+ EXPECT_EQ(0UL, dispatcher.cursor_transaction_ids_.size());
+
+ // Make a cursor request. This should record the transaction id.
+ dispatcher.RequestIDBDatabaseOpenCursor(ipc_database_id,
+ transaction_id,
+ object_store_id,
+ index_id,
+ IndexedDBKeyRange(),
+ direction,
+ key_only,
+ blink::WebIDBDatabase::NormalTask,
+ new CursorCallbacks(&cursor));
+
+ // Verify that the transaction id was captured.
+ EXPECT_EQ(1UL, dispatcher.cursor_transaction_ids_.size());
+ EXPECT_FALSE(cursor.get());
+
+ int32 ipc_callbacks_id = dispatcher.cursor_transaction_ids_.begin()->first;
+
+ // Now simululate a "null cursor" response.
+ dispatcher.OnSuccessValue(
+ dispatcher.CurrentWorkerId(), ipc_callbacks_id, std::string());
+
+ // Ensure the map result was deleted.
+ EXPECT_EQ(0UL, dispatcher.cursor_transaction_ids_.size());
+ EXPECT_FALSE(cursor.get());
+ }
+}
+
+namespace {
+
+class MockCursor : public WebIDBCursorImpl {
+ public:
+ MockCursor(int32 ipc_cursor_id,
+ int64 transaction_id,
+ ThreadSafeSender* thread_safe_sender)
+ : WebIDBCursorImpl(ipc_cursor_id, transaction_id, thread_safe_sender),
+ reset_count_(0) {}
+
+ // This method is virtual so it can be overridden in unit tests.
+ virtual void ResetPrefetchCache() OVERRIDE { ++reset_count_; }
+
+ int reset_count() const { return reset_count_; }
+
+ private:
+ int reset_count_;
+};
+
+} // namespace
+
+TEST_F(IndexedDBDispatcherTest, CursorReset) {
+ scoped_ptr<WebIDBCursor> cursor;
+ MockDispatcher dispatcher(thread_safe_sender_.get());
+
+ const int32 ipc_database_id = 0;
+ const int32 object_store_id = 0;
+ const int32 index_id = 0;
+ const bool key_only = false;
+ const int cursor1_ipc_id = 1;
+ const int cursor2_ipc_id = 2;
+ const int other_cursor_ipc_id = 2;
+ const int cursor1_transaction_id = 1;
+ const int cursor2_transaction_id = 2;
+ const int other_transaction_id = 3;
+
+ scoped_ptr<MockCursor> cursor1(
+ new MockCursor(WebIDBCursorImpl::kInvalidCursorId,
+ cursor1_transaction_id,
+ thread_safe_sender_.get()));
+
+ scoped_ptr<MockCursor> cursor2(
+ new MockCursor(WebIDBCursorImpl::kInvalidCursorId,
+ cursor2_transaction_id,
+ thread_safe_sender_.get()));
+
+ dispatcher.cursors_[cursor1_ipc_id] = cursor1.get();
+ dispatcher.cursors_[cursor2_ipc_id] = cursor2.get();
+
+ EXPECT_EQ(0, cursor1->reset_count());
+ EXPECT_EQ(0, cursor2->reset_count());
+
+ // Other transaction:
+ dispatcher.RequestIDBDatabaseGet(ipc_database_id,
+ other_transaction_id,
+ object_store_id,
+ index_id,
+ IndexedDBKeyRange(),
+ key_only,
+ new MockCallbacks());
+
+ EXPECT_EQ(0, cursor1->reset_count());
+ EXPECT_EQ(0, cursor2->reset_count());
+
+ // Same transaction:
+ dispatcher.RequestIDBDatabaseGet(ipc_database_id,
+ cursor1_transaction_id,
+ object_store_id,
+ index_id,
+ IndexedDBKeyRange(),
+ key_only,
+ new MockCallbacks());
+
+ EXPECT_EQ(1, cursor1->reset_count());
+ EXPECT_EQ(0, cursor2->reset_count());
+
+ // Same transaction and same cursor:
+ dispatcher.RequestIDBCursorContinue(IndexedDBKey(),
+ IndexedDBKey(),
+ new MockCallbacks(),
+ cursor1_ipc_id,
+ cursor1_transaction_id);
+
+ EXPECT_EQ(1, cursor1->reset_count());
+ EXPECT_EQ(0, cursor2->reset_count());
+
+ // Same transaction and different cursor:
+ dispatcher.RequestIDBCursorContinue(IndexedDBKey(),
+ IndexedDBKey(),
+ new MockCallbacks(),
+ other_cursor_ipc_id,
+ cursor1_transaction_id);
+
+ EXPECT_EQ(2, cursor1->reset_count());
+ EXPECT_EQ(0, cursor2->reset_count());
+
+ cursor1.reset();
+ cursor2.reset();
+}
+
} // namespace content
diff --git a/content/child/indexed_db/webidbcursor_impl.cc b/content/child/indexed_db/webidbcursor_impl.cc
index 50f7ebf..ad039d8 100644
--- a/content/child/indexed_db/webidbcursor_impl.cc
+++ b/content/child/indexed_db/webidbcursor_impl.cc
@@ -18,8 +18,10 @@ using blink::WebIDBKey;
namespace content {
WebIDBCursorImpl::WebIDBCursorImpl(int32 ipc_cursor_id,
+ int64 transaction_id,
ThreadSafeSender* thread_safe_sender)
: ipc_cursor_id_(ipc_cursor_id),
+ transaction_id_(transaction_id),
continue_count_(0),
used_prefetches_(0),
pending_onsuccess_callbacks_(0),
@@ -53,7 +55,7 @@ void WebIDBCursorImpl::advance(unsigned long count,
}
ResetPrefetchCache();
dispatcher->RequestIDBCursorAdvance(
- count, callbacks.release(), ipc_cursor_id_);
+ count, callbacks.release(), ipc_cursor_id_, transaction_id_);
}
void WebIDBCursorImpl::continueFunction(const WebIDBKey& key,
@@ -100,7 +102,8 @@ void WebIDBCursorImpl::continueFunction(const WebIDBKey& key,
dispatcher->RequestIDBCursorContinue(IndexedDBKeyBuilder::Build(key),
IndexedDBKeyBuilder::Build(primary_key),
callbacks.release(),
- ipc_cursor_id_);
+ ipc_cursor_id_,
+ transaction_id_);
}
void WebIDBCursorImpl::postSuccessHandlerCallback() {
diff --git a/content/child/indexed_db/webidbcursor_impl.h b/content/child/indexed_db/webidbcursor_impl.h
index 5552022..5794b00 100644
--- a/content/child/indexed_db/webidbcursor_impl.h
+++ b/content/child/indexed_db/webidbcursor_impl.h
@@ -25,7 +25,9 @@ class ThreadSafeSender;
class CONTENT_EXPORT WebIDBCursorImpl
: NON_EXPORTED_BASE(public blink::WebIDBCursor) {
public:
- WebIDBCursorImpl(int32 ipc_cursor_id, ThreadSafeSender* thread_safe_sender);
+ WebIDBCursorImpl(int32 ipc_cursor_id,
+ int64 transaction_id,
+ ThreadSafeSender* thread_safe_sender);
virtual ~WebIDBCursorImpl();
virtual void advance(unsigned long count, blink::WebIDBCallbacks* callback);
@@ -42,14 +44,21 @@ class CONTENT_EXPORT WebIDBCursorImpl
void CachedAdvance(unsigned long count, blink::WebIDBCallbacks* callbacks);
void CachedContinue(blink::WebIDBCallbacks* callbacks);
- void ResetPrefetchCache();
+
+ // This method is virtual so it can be overridden in unit tests.
+ virtual void ResetPrefetchCache();
+
+ int64 transaction_id() const { return transaction_id_; }
private:
- FRIEND_TEST_ALL_PREFIXES(WebIDBCursorImplTest, PrefetchTest);
+ FRIEND_TEST_ALL_PREFIXES(IndexedDBDispatcherTest, CursorReset);
+ FRIEND_TEST_ALL_PREFIXES(IndexedDBDispatcherTest, CursorTransactionId);
FRIEND_TEST_ALL_PREFIXES(WebIDBCursorImplTest, AdvancePrefetchTest);
FRIEND_TEST_ALL_PREFIXES(WebIDBCursorImplTest, PrefetchReset);
+ FRIEND_TEST_ALL_PREFIXES(WebIDBCursorImplTest, PrefetchTest);
int32 ipc_cursor_id_;
+ int64 transaction_id_;
// Prefetch cache.
std::deque<IndexedDBKey> prefetch_keys_;
diff --git a/content/child/indexed_db/webidbcursor_impl_unittest.cc b/content/child/indexed_db/webidbcursor_impl_unittest.cc
index 1115950..33494e0 100644
--- a/content/child/indexed_db/webidbcursor_impl_unittest.cc
+++ b/content/child/indexed_db/webidbcursor_impl_unittest.cc
@@ -53,7 +53,8 @@ class MockDispatcher : public IndexedDBDispatcher {
virtual void RequestIDBCursorAdvance(unsigned long count,
WebIDBCallbacks* callbacks,
- int32 ipc_cursor_id) OVERRIDE {
+ int32 ipc_cursor_id,
+ int64 transaction_id) OVERRIDE {
++advance_calls_;
callbacks_.reset(callbacks);
}
@@ -61,7 +62,8 @@ class MockDispatcher : public IndexedDBDispatcher {
virtual void RequestIDBCursorContinue(const IndexedDBKey& key,
const IndexedDBKey& primary_key,
WebIDBCallbacks* callbacks,
- int32 ipc_cursor_id) OVERRIDE {
+ int32 ipc_cursor_id,
+ int64 transaction_id) OVERRIDE {
++continue_calls_;
callbacks_.reset(callbacks);
}
@@ -131,8 +133,10 @@ class WebIDBCursorImplTest : public testing::Test {
TEST_F(WebIDBCursorImplTest, PrefetchTest) {
+ const int64 transaction_id = 1;
{
WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
+ transaction_id,
thread_safe_sender_.get());
// Call continue() until prefetching should kick in.
@@ -195,7 +199,9 @@ TEST_F(WebIDBCursorImplTest, PrefetchTest) {
TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) {
+ const int64 transaction_id = 1;
WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
+ transaction_id,
thread_safe_sender_.get());
// Call continue() until prefetching should kick in.
@@ -261,7 +267,9 @@ TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) {
}
TEST_F(WebIDBCursorImplTest, PrefetchReset) {
+ const int64 transaction_id = 1;
WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
+ transaction_id,
thread_safe_sender_.get());
// Call continue() until prefetching should kick in.
diff --git a/content/child/thread_safe_sender.h b/content/child/thread_safe_sender.h
index 71e7c08..6cd5c75 100644
--- a/content/child/thread_safe_sender.h
+++ b/content/child/thread_safe_sender.h
@@ -30,9 +30,9 @@ class CONTENT_EXPORT ThreadSafeSender
private:
friend class ChildThread; // for construction
+ friend class IndexedDBDispatcherTest;
friend class WebIDBCursorImplTest;
friend class base::RefCountedThreadSafe<ThreadSafeSender>;
- FRIEND_TEST_ALL_PREFIXES(IndexedDBDispatcherTest, ValueSizeTest);
ThreadSafeSender(base::MessageLoopProxy* main_loop,
IPC::SyncMessageFilter* sync_filter);
diff --git a/content/common/indexed_db/indexed_db_messages.h b/content/common/indexed_db/indexed_db_messages.h
index 365d129..6f88964 100644
--- a/content/common/indexed_db/indexed_db_messages.h
+++ b/content/common/indexed_db/indexed_db_messages.h
@@ -16,6 +16,8 @@
#include "third_party/WebKit/public/platform/WebIDBCursor.h"
#include "third_party/WebKit/public/platform/WebIDBDatabase.h"
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
#define IPC_MESSAGE_START IndexedDBMsgStart
// Argument structures used in messages