blob: 60c171ad204a0ebb7604d0e36db0e71e1ca687d1 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/indexed_db/cursor_impl.h"
#include "base/memory/ptr_util.h"
#include "base/sequenced_task_runner.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
#include "content/browser/indexed_db/indexed_db_cursor.h"
#include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
namespace content {
// Expected to be constructed on IO thread, and used/destroyed on IDB thread.
class CursorImpl::IDBThreadHelper {
public:
explicit IDBThreadHelper(std::unique_ptr<IndexedDBCursor> cursor);
~IDBThreadHelper();
void Advance(uint32_t count, scoped_refptr<IndexedDBCallbacks> callbacks);
void Continue(const IndexedDBKey& key,
const IndexedDBKey& primary_key,
scoped_refptr<IndexedDBCallbacks> callbacks);
void Prefetch(int32_t count, scoped_refptr<IndexedDBCallbacks> callbacks);
void PrefetchReset(int32_t used_prefetches, int32_t unused_prefetches);
private:
std::unique_ptr<IndexedDBCursor> cursor_;
DISALLOW_COPY_AND_ASSIGN(IDBThreadHelper);
};
CursorImpl::CursorImpl(std::unique_ptr<IndexedDBCursor> cursor,
const url::Origin& origin,
IndexedDBDispatcherHost* dispatcher_host,
scoped_refptr<base::SequencedTaskRunner> idb_runner)
: helper_(new IDBThreadHelper(std::move(cursor))),
dispatcher_host_(dispatcher_host),
origin_(origin),
idb_runner_(std::move(idb_runner)) {}
CursorImpl::~CursorImpl() {
idb_runner_->DeleteSoon(FROM_HERE, helper_);
}
void CursorImpl::Advance(
uint32_t count,
::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
scoped_refptr<IndexedDBCallbacks> callbacks(
new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
std::move(callbacks_info), idb_runner_));
idb_runner_->PostTask(FROM_HERE, base::Bind(&IDBThreadHelper::Advance,
base::Unretained(helper_), count,
base::Passed(&callbacks)));
}
void CursorImpl::Continue(
const IndexedDBKey& key,
const IndexedDBKey& primary_key,
::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
scoped_refptr<IndexedDBCallbacks> callbacks(
new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
std::move(callbacks_info), idb_runner_));
idb_runner_->PostTask(
FROM_HERE,
base::Bind(&IDBThreadHelper::Continue, base::Unretained(helper_), key,
primary_key, base::Passed(&callbacks)));
}
void CursorImpl::Prefetch(
int32_t count,
::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
scoped_refptr<IndexedDBCallbacks> callbacks(
new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
std::move(callbacks_info), idb_runner_));
idb_runner_->PostTask(FROM_HERE, base::Bind(&IDBThreadHelper::Prefetch,
base::Unretained(helper_), count,
base::Passed(&callbacks)));
}
void CursorImpl::PrefetchReset(
int32_t used_prefetches,
int32_t unused_prefetches,
const std::vector<std::string>& unused_blob_uuids) {
for (const auto& uuid : unused_blob_uuids)
dispatcher_host_->DropBlobData(uuid);
idb_runner_->PostTask(
FROM_HERE,
base::Bind(&IDBThreadHelper::PrefetchReset, base::Unretained(helper_),
used_prefetches, unused_prefetches));
}
CursorImpl::IDBThreadHelper::IDBThreadHelper(
std::unique_ptr<IndexedDBCursor> cursor)
: cursor_(std::move(cursor)) {}
CursorImpl::IDBThreadHelper::~IDBThreadHelper() {}
void CursorImpl::IDBThreadHelper::Advance(
uint32_t count,
scoped_refptr<IndexedDBCallbacks> callbacks) {
cursor_->Advance(count, std::move(callbacks));
}
void CursorImpl::IDBThreadHelper::Continue(
const IndexedDBKey& key,
const IndexedDBKey& primary_key,
scoped_refptr<IndexedDBCallbacks> callbacks) {
cursor_->Continue(
key.IsValid() ? base::MakeUnique<IndexedDBKey>(key) : nullptr,
primary_key.IsValid() ? base::MakeUnique<IndexedDBKey>(primary_key)
: nullptr,
std::move(callbacks));
}
void CursorImpl::IDBThreadHelper::Prefetch(
int32_t count,
scoped_refptr<IndexedDBCallbacks> callbacks) {
cursor_->PrefetchContinue(count, std::move(callbacks));
}
void CursorImpl::IDBThreadHelper::PrefetchReset(int32_t used_prefetches,
int32_t unused_prefetches) {
leveldb::Status s =
cursor_->PrefetchReset(used_prefetches, unused_prefetches);
// TODO(cmumford): Handle this error (crbug.com/363397)
if (!s.ok())
DLOG(ERROR) << "Unable to reset prefetch";
}
} // namespace content