Commit 9a58b89a authored by Chase Phillips's avatar Chase Phillips Committed by Commit Bot

IndexedDB: Make IDBCursor.Advance() use native Mojo callback

IDBCursor.Advance() previously took a separate IDBCallbacks interface
that had its own lifecycle and could have a number of methods called
on it.

This change updates Advance() to use Mojo's native callback mechanism
so we can start moving away from the complicated IDBCallbacks
interface and instead use a simpler and easier to reason about async
response return approach.

Bug: 717812
Change-Id: Ia08bebfcafe5f63d60366e81b7f973b1e9ad2378
Reviewed-on: https://chromium-review.googlesource.com/c/1336662
Commit-Queue: Chase Phillips <cmp@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#622176}
parent a3fea651
...@@ -19,7 +19,9 @@ class CursorImpl::IDBSequenceHelper { ...@@ -19,7 +19,9 @@ class CursorImpl::IDBSequenceHelper {
explicit IDBSequenceHelper(std::unique_ptr<IndexedDBCursor> cursor); explicit IDBSequenceHelper(std::unique_ptr<IndexedDBCursor> cursor);
~IDBSequenceHelper(); ~IDBSequenceHelper();
void Advance(uint32_t count, scoped_refptr<IndexedDBCallbacks> callbacks); void Advance(uint32_t count,
base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
blink::mojom::IDBCursor::AdvanceCallback callback);
void Continue(const IndexedDBKey& key, void Continue(const IndexedDBKey& key,
const IndexedDBKey& primary_key, const IndexedDBKey& primary_key,
scoped_refptr<IndexedDBCallbacks> callbacks); scoped_refptr<IndexedDBCallbacks> callbacks);
...@@ -45,15 +47,13 @@ CursorImpl::~CursorImpl() { ...@@ -45,15 +47,13 @@ CursorImpl::~CursorImpl() {
idb_runner_->DeleteSoon(FROM_HERE, helper_); idb_runner_->DeleteSoon(FROM_HERE, helper_);
} }
void CursorImpl::Advance( void CursorImpl::Advance(uint32_t count,
uint32_t count, blink::mojom::IDBCursor::AdvanceCallback callback) {
blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info) { idb_runner_->PostTask(
scoped_refptr<IndexedDBCallbacks> callbacks( FROM_HERE,
new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_, base::BindOnce(&IDBSequenceHelper::Advance, base::Unretained(helper_),
std::move(callbacks_info), idb_runner_)); count, dispatcher_host_->AsWeakPtr(),
idb_runner_->PostTask(FROM_HERE, base::BindOnce(&IDBSequenceHelper::Advance, std::move(callback)));
base::Unretained(helper_),
count, std::move(callbacks)));
} }
void CursorImpl::CursorContinue( void CursorImpl::CursorContinue(
...@@ -96,8 +96,9 @@ CursorImpl::IDBSequenceHelper::~IDBSequenceHelper() {} ...@@ -96,8 +96,9 @@ CursorImpl::IDBSequenceHelper::~IDBSequenceHelper() {}
void CursorImpl::IDBSequenceHelper::Advance( void CursorImpl::IDBSequenceHelper::Advance(
uint32_t count, uint32_t count,
scoped_refptr<IndexedDBCallbacks> callbacks) { base::WeakPtr<content::IndexedDBDispatcherHost> dispatcher_host,
cursor_->Advance(count, std::move(callbacks)); blink::mojom::IDBCursor::AdvanceCallback callback) {
cursor_->Advance(count, std::move(dispatcher_host), std::move(callback));
} }
void CursorImpl::IDBSequenceHelper::Continue( void CursorImpl::IDBSequenceHelper::Continue(
......
...@@ -31,7 +31,7 @@ class CursorImpl : public blink::mojom::IDBCursor { ...@@ -31,7 +31,7 @@ class CursorImpl : public blink::mojom::IDBCursor {
// blink::mojom::IDBCursor implementation // blink::mojom::IDBCursor implementation
void Advance(uint32_t count, void Advance(uint32_t count,
blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks) override; blink::mojom::IDBCursor::AdvanceCallback callback) override;
void CursorContinue( void CursorContinue(
const blink::IndexedDBKey& key, const blink::IndexedDBKey& key,
const blink::IndexedDBKey& primary_key, const blink::IndexedDBKey& primary_key,
......
...@@ -10,11 +10,14 @@ ...@@ -10,11 +10,14 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/task/post_task.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h" #include "content/browser/indexed_db/indexed_db_callbacks.h"
#include "content/browser/indexed_db/indexed_db_database_error.h" #include "content/browser/indexed_db/indexed_db_database_error.h"
#include "content/browser/indexed_db/indexed_db_tracing.h" #include "content/browser/indexed_db/indexed_db_tracing.h"
#include "content/browser/indexed_db/indexed_db_transaction.h" #include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/indexed_db_value.h" #include "content/browser/indexed_db/indexed_db_value.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h"
using blink::IndexedDBKey; using blink::IndexedDBKey;
...@@ -95,24 +98,40 @@ void IndexedDBCursor::Continue(std::unique_ptr<IndexedDBKey> key, ...@@ -95,24 +98,40 @@ void IndexedDBCursor::Continue(std::unique_ptr<IndexedDBKey> key,
base::Passed(&primary_key), callbacks)); base::Passed(&primary_key), callbacks));
} }
void IndexedDBCursor::Advance(uint32_t count, void IndexedDBCursor::Advance(
scoped_refptr<IndexedDBCallbacks> callbacks) { uint32_t count,
base::WeakPtr<content::IndexedDBDispatcherHost> dispatcher_host,
blink::mojom::IDBCursor::AdvanceCallback callback) {
IDB_TRACE("IndexedDBCursor::Advance"); IDB_TRACE("IndexedDBCursor::Advance");
if (closed_) { if (closed_) {
callbacks->OnError(CreateCursorClosedError()); base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(
[](blink::mojom::IDBCursor::AdvanceCallback callback) {
const IndexedDBDatabaseError closed_error(
CreateCursorClosedError());
DCHECK_NE(closed_error.code(), 0);
std::move(callback).Run(
blink::mojom::IDBError::New(closed_error.code(),
closed_error.message()),
blink::mojom::IDBCursorValuePtr());
},
std::move(callback)));
return; return;
} }
transaction_->ScheduleTask( transaction_->ScheduleTask(
task_type_, task_type_,
BindWeakOperation(&IndexedDBCursor::CursorAdvanceOperation, BindWeakOperation(&IndexedDBCursor::CursorAdvanceOperation,
ptr_factory_.GetWeakPtr(), count, callbacks)); ptr_factory_.GetWeakPtr(), count,
std::move(dispatcher_host), std::move(callback)));
} }
leveldb::Status IndexedDBCursor::CursorAdvanceOperation( leveldb::Status IndexedDBCursor::CursorAdvanceOperation(
uint32_t count, uint32_t count,
scoped_refptr<IndexedDBCallbacks> callbacks, base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
blink::mojom::IDBCursor::AdvanceCallback callback,
IndexedDBTransaction* /*transaction*/) { IndexedDBTransaction* /*transaction*/) {
IDB_TRACE("IndexedDBCursor::CursorAdvanceOperation"); IDB_TRACE("IndexedDBCursor::CursorAdvanceOperation");
leveldb::Status s = leveldb::Status::OK(); leveldb::Status s = leveldb::Status::OK();
...@@ -120,16 +139,66 @@ leveldb::Status IndexedDBCursor::CursorAdvanceOperation( ...@@ -120,16 +139,66 @@ leveldb::Status IndexedDBCursor::CursorAdvanceOperation(
if (!cursor_ || !cursor_->Advance(count, &s)) { if (!cursor_ || !cursor_->Advance(count, &s)) {
cursor_.reset(); cursor_.reset();
if (s.ok()) { if (s.ok()) {
callbacks->OnSuccess(nullptr); base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(
[](blink::mojom::IDBCursor::AdvanceCallback callback) {
std::move(callback).Run(blink::mojom::IDBErrorPtr(),
blink::mojom::IDBCursorValuePtr());
},
std::move(callback)));
return s; return s;
} }
Close(); Close();
callbacks->OnError(IndexedDBDatabaseError(
blink::kWebIDBDatabaseExceptionUnknownError, "Error advancing cursor")); base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(
[](blink::mojom::IDBCursor::AdvanceCallback callback) {
std::move(callback).Run(
blink::mojom::IDBError::New(
blink::kWebIDBDatabaseExceptionUnknownError,
base::ASCIIToUTF16("Error advancing cursor")),
blink::mojom::IDBCursorValuePtr());
},
std::move(callback)));
return s; return s;
} }
callbacks->OnSuccess(key(), primary_key(), Value()); base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(
[](base::WeakPtr<content::IndexedDBDispatcherHost> dispatcher_host,
blink::mojom::IDBCursor::AdvanceCallback callback,
IndexedDBKey key, IndexedDBKey primary_key,
IndexedDBValue* value) {
if (!dispatcher_host)
return;
blink::mojom::IDBValuePtr mojo_value;
std::vector<IndexedDBBlobInfo> blob_info;
if (value) {
mojo_value = IndexedDBValue::ConvertAndEraseValue(value);
blob_info.swap(value->blob_info);
if (!IndexedDBCallbacks::CreateAllBlobs(
dispatcher_host->blob_storage_context(),
dispatcher_host->context(), blob_info,
&mojo_value->blob_or_file_info))
return;
} else {
mojo_value = blink::mojom::IDBValue::New();
}
blink::mojom::IDBCursorValuePtr cursor_value =
blink::mojom::IDBCursorValue::New(std::move(key),
std::move(primary_key),
std::move(mojo_value));
std::move(callback).Run(blink::mojom::IDBErrorPtr(),
std::move(cursor_value));
},
std::move(dispatcher_host), std::move(callback), key(), primary_key(),
Value()));
return s; return s;
} }
......
...@@ -29,7 +29,9 @@ class CONTENT_EXPORT IndexedDBCursor { ...@@ -29,7 +29,9 @@ class CONTENT_EXPORT IndexedDBCursor {
IndexedDBTransaction* transaction); IndexedDBTransaction* transaction);
~IndexedDBCursor(); ~IndexedDBCursor();
void Advance(uint32_t count, scoped_refptr<IndexedDBCallbacks> callbacks); void Advance(uint32_t count,
base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
blink::mojom::IDBCursor::AdvanceCallback callback);
void Continue(std::unique_ptr<blink::IndexedDBKey> key, void Continue(std::unique_ptr<blink::IndexedDBKey> key,
std::unique_ptr<blink::IndexedDBKey> primary_key, std::unique_ptr<blink::IndexedDBKey> primary_key,
scoped_refptr<IndexedDBCallbacks> callbacks); scoped_refptr<IndexedDBCallbacks> callbacks);
...@@ -55,7 +57,8 @@ class CONTENT_EXPORT IndexedDBCursor { ...@@ -55,7 +57,8 @@ class CONTENT_EXPORT IndexedDBCursor {
IndexedDBTransaction* transaction); IndexedDBTransaction* transaction);
leveldb::Status CursorAdvanceOperation( leveldb::Status CursorAdvanceOperation(
uint32_t count, uint32_t count,
scoped_refptr<IndexedDBCallbacks> callbacks, base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
blink::mojom::IDBCursor::AdvanceCallback callback,
IndexedDBTransaction* transaction); IndexedDBTransaction* transaction);
leveldb::Status CursorPrefetchIterationOperation( leveldb::Status CursorPrefetchIterationOperation(
int number_to_fetch, int number_to_fetch,
......
...@@ -269,11 +269,28 @@ interface IDBDatabaseCallbacks { ...@@ -269,11 +269,28 @@ interface IDBDatabaseCallbacks {
Changes(IDBObserverChanges changes); Changes(IDBObserverChanges changes);
}; };
struct IDBError {
int32 error_code;
mojo_base.mojom.String16 error_message;
};
struct IDBCursorValue {
IDBKey key;
IDBKey primary_key;
IDBValue value;
};
interface IDBCursor { interface IDBCursor {
Advance(uint32 count, associated IDBCallbacks callbacks); // Advance() can call its return callback in one of 3 ways:
// * with |error| set and |value| unset, if an error occurs
// * with |error| unset and |value| set, under normal operation
// * with |error| unset and |value| unset, under normal operation when the end
// of the source being iterated is reached
Advance(uint32 count) => (IDBError? error, IDBCursorValue? value);
// Avoid calling the following function "Continue" since the Mojo // Avoid calling the following function "Continue" since the Mojo
// Java bindings generate incorrect Java as a result. We've named // Java bindings generate incorrect Java as a result. We've named
// the following funciton "CursorContinue" as a workaround. // the following function "CursorContinue" as a workaround.
CursorContinue(IDBKey key, CursorContinue(IDBKey key,
IDBKey primary_key, IDBKey primary_key,
associated IDBCallbacks callbacks); associated IDBCallbacks callbacks);
......
...@@ -93,12 +93,12 @@ class WebIDBCallbacksImpl final : public WebIDBCallbacks { ...@@ -93,12 +93,12 @@ class WebIDBCallbacksImpl final : public WebIDBCallbacks {
const IDBDatabaseMetadata&) override; const IDBDatabaseMetadata&) override;
void DetachRequestFromCallback() override; void DetachRequestFromCallback() override;
void Detach();
void DetachCallbackFromRequest();
private: private:
explicit WebIDBCallbacksImpl(IDBRequest*); explicit WebIDBCallbacksImpl(IDBRequest*);
void Detach();
void DetachCallbackFromRequest();
Persistent<IDBRequest> request_; Persistent<IDBRequest> request_;
base::WeakPtr<WebIDBCursorImpl> cursor_; base::WeakPtr<WebIDBCursorImpl> cursor_;
int64_t transaction_id_; int64_t transaction_id_;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "mojo/public/cpp/bindings/strong_associated_binding.h" #include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h"
#include "third_party/blink/renderer/modules/indexeddb/indexed_db_dispatcher.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_dispatcher.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
using blink::mojom::blink::IDBCallbacksAssociatedPtrInfo; using blink::mojom::blink::IDBCallbacksAssociatedPtrInfo;
using blink::mojom::blink::IDBCursorAssociatedPtrInfo; using blink::mojom::blink::IDBCursorAssociatedPtrInfo;
...@@ -49,7 +50,31 @@ void WebIDBCursorImpl::Advance(uint32_t count, WebIDBCallbacks* callbacks_ptr) { ...@@ -49,7 +50,31 @@ void WebIDBCursorImpl::Advance(uint32_t count, WebIDBCallbacks* callbacks_ptr) {
ResetPrefetchCache(); ResetPrefetchCache();
callbacks->SetState(weak_factory_.GetWeakPtr(), transaction_id_); callbacks->SetState(weak_factory_.GetWeakPtr(), transaction_id_);
cursor_->Advance(count, GetCallbacksProxy(std::move(callbacks))); cursor_->Advance(count,
WTF::Bind(&WebIDBCursorImpl::AdvanceCallback,
WTF::Unretained(this), std::move(callbacks)));
}
void WebIDBCursorImpl::AdvanceCallback(
std::unique_ptr<WebIDBCallbacks> callbacks,
mojom::blink::IDBErrorPtr error,
mojom::blink::IDBCursorValuePtr cursor_value) {
if (error) {
callbacks->Error(error->error_code, error->error_message);
callbacks.reset();
return;
}
if (!cursor_value) {
callbacks->SuccessValue(nullptr);
callbacks.reset();
return;
}
callbacks->SuccessCursorContinue(std::move(cursor_value->key),
std::move(cursor_value->primary_key),
std::move(cursor_value->value));
callbacks.reset();
} }
void WebIDBCursorImpl::CursorContinue(const IDBKey* key, void WebIDBCursorImpl::CursorContinue(const IDBKey* key,
......
...@@ -25,6 +25,7 @@ class MODULES_EXPORT WebIDBCursorImpl : public WebIDBCursor { ...@@ -25,6 +25,7 @@ class MODULES_EXPORT WebIDBCursorImpl : public WebIDBCursor {
~WebIDBCursorImpl() override; ~WebIDBCursorImpl() override;
void Advance(uint32_t count, WebIDBCallbacks* callback) override; void Advance(uint32_t count, WebIDBCallbacks* callback) override;
void CursorContinue(const IDBKey* key, void CursorContinue(const IDBKey* key,
const IDBKey* primary_key, const IDBKey* primary_key,
WebIDBCallbacks* callback) override; WebIDBCallbacks* callback) override;
...@@ -43,6 +44,9 @@ class MODULES_EXPORT WebIDBCursorImpl : public WebIDBCursor { ...@@ -43,6 +44,9 @@ class MODULES_EXPORT WebIDBCursorImpl : public WebIDBCursor {
int64_t transaction_id() const { return transaction_id_; } int64_t transaction_id() const { return transaction_id_; }
private: private:
void AdvanceCallback(std::unique_ptr<WebIDBCallbacks> callbacks,
mojom::blink::IDBErrorPtr error,
mojom::blink::IDBCursorValuePtr value);
mojom::blink::IDBCallbacksAssociatedPtrInfo GetCallbacksProxy( mojom::blink::IDBCallbacksAssociatedPtrInfo GetCallbacksProxy(
std::unique_ptr<WebIDBCallbacks> callbacks); std::unique_ptr<WebIDBCallbacks> callbacks);
......
...@@ -44,8 +44,10 @@ class MockCursorImpl : public mojom::blink::IDBCursor { ...@@ -44,8 +44,10 @@ class MockCursorImpl : public mojom::blink::IDBCursor {
} }
void Advance(uint32_t count, void Advance(uint32_t count,
mojom::blink::IDBCallbacksAssociatedPtrInfo callbacks) override { mojom::blink::IDBCursor::AdvanceCallback callback) override {
++advance_calls_; ++advance_calls_;
std::move(callback).Run(mojom::blink::IDBErrorPtr(),
mojom::blink::IDBCursorValuePtr());
} }
void CursorContinue( void CursorContinue(
...@@ -83,6 +85,10 @@ class MockContinueCallbacks : public testing::StrictMock<MockWebIDBCallbacks> { ...@@ -83,6 +85,10 @@ class MockContinueCallbacks : public testing::StrictMock<MockWebIDBCallbacks> {
Vector<WebBlobInfo>* blobs = nullptr) Vector<WebBlobInfo>* blobs = nullptr)
: key_(key), blobs_(blobs) {} : key_(key), blobs_(blobs) {}
void SetState(base::WeakPtr<WebIDBCursorImpl> cursor,
int64_t transaction_id) override {}
void SuccessValue(mojom::blink::IDBReturnValuePtr return_value) override {}
void SuccessCursorContinue( void SuccessCursorContinue(
std::unique_ptr<IDBKey> key, std::unique_ptr<IDBKey> key,
std::unique_ptr<IDBKey> primaryKey, std::unique_ptr<IDBKey> primaryKey,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment