summaryrefslogtreecommitdiff
path: root/chromium/content/browser/indexed_db/indexed_db_cursor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/indexed_db/indexed_db_cursor.cc')
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_cursor.cc35
1 files changed, 34 insertions, 1 deletions
diff --git a/chromium/content/browser/indexed_db/indexed_db_cursor.cc b/chromium/content/browser/indexed_db/indexed_db_cursor.cc
index a029b08242f..915c4276543 100644
--- a/chromium/content/browser/indexed_db/indexed_db_cursor.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_cursor.cc
@@ -15,8 +15,21 @@
#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_value.h"
+#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseException.h"
namespace content {
+namespace {
+// This should never be script visible: the cursor should either be closed when
+// it hits the end of the range (and script throws an error before the call
+// could be made), if the transaction has finished (ditto), or if there's an
+// incoming request from the front end but the transaction has aborted on the
+// back end; in that case the tx will already have sent an abort to the request
+// so this would be ignored.
+IndexedDBDatabaseError CreateCursorClosedError() {
+ return IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError,
+ "The cursor has been closed.");
+}
+} // namespace
IndexedDBCursor::IndexedDBCursor(
std::unique_ptr<IndexedDBBackingStore::Cursor> cursor,
@@ -32,7 +45,8 @@ IndexedDBCursor::IndexedDBCursor(
}
IndexedDBCursor::~IndexedDBCursor() {
- transaction_->UnregisterOpenCursor(this);
+ // Call to make sure we complete our lifetime trace.
+ Close();
}
void IndexedDBCursor::Continue(std::unique_ptr<IndexedDBKey> key,
@@ -40,6 +54,11 @@ void IndexedDBCursor::Continue(std::unique_ptr<IndexedDBKey> key,
scoped_refptr<IndexedDBCallbacks> callbacks) {
IDB_TRACE("IndexedDBCursor::Continue");
+ if (closed_) {
+ callbacks->OnError(CreateCursorClosedError());
+ return;
+ }
+
transaction_->ScheduleTask(
task_type_,
base::Bind(&IndexedDBCursor::CursorIterationOperation,
@@ -53,6 +72,11 @@ void IndexedDBCursor::Advance(uint32_t count,
scoped_refptr<IndexedDBCallbacks> callbacks) {
IDB_TRACE("IndexedDBCursor::Advance");
+ if (closed_) {
+ callbacks->OnError(CreateCursorClosedError());
+ return;
+ }
+
transaction_->ScheduleTask(
task_type_,
base::Bind(
@@ -104,6 +128,11 @@ void IndexedDBCursor::PrefetchContinue(
scoped_refptr<IndexedDBCallbacks> callbacks) {
IDB_TRACE("IndexedDBCursor::PrefetchContinue");
+ if (closed_) {
+ callbacks->OnError(CreateCursorClosedError());
+ return;
+ }
+
transaction_->ScheduleTask(
task_type_,
base::Bind(&IndexedDBCursor::CursorPrefetchIterationOperation,
@@ -198,10 +227,14 @@ leveldb::Status IndexedDBCursor::PrefetchReset(int used_prefetches,
}
void IndexedDBCursor::Close() {
+ if (closed_)
+ return;
IDB_TRACE("IndexedDBCursor::Close");
closed_ = true;
cursor_.reset();
saved_cursor_.reset();
+ if (transaction_)
+ transaction_->UnregisterOpenCursor(this);
}
} // namespace content