Title: [130095] trunk/Source
Revision
130095
Author
jsb...@chromium.org
Date
2012-10-01 16:14:13 -0700 (Mon, 01 Oct 2012)

Log Message

Source/WebCore: IndexedDB: Fire error rather than raising on request creation if transaction aborts asynchronously.
https://bugs.webkit.org/show_bug.cgi?id=93054

Reviewed by Tony Chang.

All IDB data operations are asynchronous, producing IDBRequest objects. This was implemented
by passing all data from the front-end to the back-end synchronously, and synchronously
returning an exception code back if the request was invalid. Previous changes have moved
request validation to the front-end except for the case of the back-end transaction having
asynchronously aborted in the mean time.

To eliminate that case (which would allow front-end to back-end communication to be
asynchronous in multi-process ports), change from returning an exception code to relying on
the front-end to abort the request when the abort event finally arrives.

The difference would be noticeable in scripts - in a multi-process environment:

var request1 = store.get(0);
request1._onerror_ = errorHandler; // (A)
// (B)
var request2 = store.get(0); // (C)
request2._onerror_ = errorHandler; // (D)

If the transaction back-end were to asynchronously abort at exactly point (B), then prior to
this patch an exception would be thrown at (C). With this patch, no exception but (D) would
fire, same as (A).

The back-end explicitly fires an error callback as well, as intermediate layers may rely on
this to stop tracking the pending callback.

No new layout tests - change is not observable in single-process ports.
Added webkit_unit_test IDBRequestTest.AbortErrorAfterAbort to verify that IDBRequest
is resilient to this pattern, but it was previous.

* Modules/indexeddb/IDBCursor.cpp:
(WebCore::IDBCursor::advance): Back end should never fail a request.
(WebCore::IDBCursor::continueFunction): Ditto.
(WebCore::IDBCursor::deleteFunction): Ditto, and also move "is key cursor" test
here from back-end.
* Modules/indexeddb/IDBCursorBackendImpl.cpp:
(WebCore::IDBCursorBackendImpl::continueFunction): Change from EC to firing error.
(WebCore::IDBCursorBackendImpl::advance): Ditto.
(WebCore::IDBCursorBackendImpl::deleteFunction): Ditto, and remove test moved to FE.
(WebCore::IDBCursorBackendImpl::prefetchContinue): Ditto.
* Modules/indexeddb/IDBDatabaseError.cpp:
(WebCore::IDBDatabaseError::create): Add overload that looks up message via code.
(WebCore::IDBDatabaseError::IDBDatabaseError): Look up message via exception table.
* Modules/indexeddb/IDBDatabaseException.h: Add getErrorDescription.
* Modules/indexeddb/IDBDatabaseException.cpp: Implementation of getErrorDescription.
* Modules/indexeddb/IDBIndex.cpp:
(WebCore::IDBIndex::openCursor): Back end should never fail a request.
(WebCore::IDBIndex::count): Ditto.
(WebCore::IDBIndex::openKeyCursor): Ditto.
(WebCore::IDBIndex::get): Ditto.
(WebCore::IDBIndex::getKey): Ditto.
* Modules/indexeddb/IDBIndexBackendImpl.cpp:
(WebCore::IDBIndexBackendImpl::openCursor): Change from EC to firing error.
(WebCore::IDBIndexBackendImpl::openKeyCursor): Ditto.
(WebCore::IDBIndexBackendImpl::count): Ditto.
(WebCore::IDBIndexBackendImpl::get): Ditto.
(WebCore::IDBIndexBackendImpl::getKey): Ditto.
* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::get): Back end should never fail a request.
(WebCore::IDBObjectStore::put): Ditto.
(WebCore::IDBObjectStore::deleteFunction): Ditto.
(WebCore::IDBObjectStore::clear): Ditto.
(WebCore): Ditto.
(WebCore::IDBObjectStore::openCursor): Ditto.
(WebCore::IDBObjectStore::count): Ditto.
* Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
(WebCore::IDBObjectStoreBackendImpl::get): Change from EC to firing error.
(WebCore::IDBObjectStoreBackendImpl::putWithIndexKeys): Ditto.
(WebCore):
(WebCore::IDBObjectStoreBackendImpl::deleteFunction): Ditto.
(WebCore::IDBObjectStoreBackendImpl::clear): Ditto.
(WebCore::IDBObjectStoreBackendImpl::openCursor): Ditto.
(WebCore::IDBObjectStoreBackendImpl::count): Ditto.

Source/WebKit/chromium: IndexedDB: Move onSuccess(IDBDatabaseBackendInterface) to IDBOpenDBRequest
https://bugs.webkit.org/show_bug.cgi?id=94757

Reviewed by Tony Chang.

* tests/IDBRequestTest.cpp: Ensure IDBRequest can handle Error after abort.
(WebCore::TEST): Added AbortAfter

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (130094 => 130095)


--- trunk/Source/WebCore/ChangeLog	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/ChangeLog	2012-10-01 23:14:13 UTC (rev 130095)
@@ -1,3 +1,83 @@
+2012-10-01  Joshua Bell  <jsb...@chromium.org>
+
+        IndexedDB: Fire error rather than raising on request creation if transaction aborts asynchronously.
+        https://bugs.webkit.org/show_bug.cgi?id=93054
+
+        Reviewed by Tony Chang.
+
+        All IDB data operations are asynchronous, producing IDBRequest objects. This was implemented
+        by passing all data from the front-end to the back-end synchronously, and synchronously
+        returning an exception code back if the request was invalid. Previous changes have moved
+        request validation to the front-end except for the case of the back-end transaction having
+        asynchronously aborted in the mean time.
+
+        To eliminate that case (which would allow front-end to back-end communication to be
+        asynchronous in multi-process ports), change from returning an exception code to relying on
+        the front-end to abort the request when the abort event finally arrives.
+
+        The difference would be noticeable in scripts - in a multi-process environment:
+
+        var request1 = store.get(0);
+        request1._onerror_ = errorHandler; // (A)
+        // (B)
+        var request2 = store.get(0); // (C)
+        request2._onerror_ = errorHandler; // (D)
+
+        If the transaction back-end were to asynchronously abort at exactly point (B), then prior to
+        this patch an exception would be thrown at (C). With this patch, no exception but (D) would
+        fire, same as (A).
+
+        The back-end explicitly fires an error callback as well, as intermediate layers may rely on
+        this to stop tracking the pending callback.
+
+        No new layout tests - change is not observable in single-process ports.
+        Added webkit_unit_test IDBRequestTest.AbortErrorAfterAbort to verify that IDBRequest
+        is resilient to this pattern, but it was previous.
+
+        * Modules/indexeddb/IDBCursor.cpp:
+        (WebCore::IDBCursor::advance): Back end should never fail a request.
+        (WebCore::IDBCursor::continueFunction): Ditto.
+        (WebCore::IDBCursor::deleteFunction): Ditto, and also move "is key cursor" test
+        here from back-end.
+        * Modules/indexeddb/IDBCursorBackendImpl.cpp:
+        (WebCore::IDBCursorBackendImpl::continueFunction): Change from EC to firing error.
+        (WebCore::IDBCursorBackendImpl::advance): Ditto.
+        (WebCore::IDBCursorBackendImpl::deleteFunction): Ditto, and remove test moved to FE.
+        (WebCore::IDBCursorBackendImpl::prefetchContinue): Ditto.
+        * Modules/indexeddb/IDBDatabaseError.cpp:
+        (WebCore::IDBDatabaseError::create): Add overload that looks up message via code.
+        (WebCore::IDBDatabaseError::IDBDatabaseError): Look up message via exception table.
+        * Modules/indexeddb/IDBDatabaseException.h: Add getErrorDescription.
+        * Modules/indexeddb/IDBDatabaseException.cpp: Implementation of getErrorDescription.
+        * Modules/indexeddb/IDBIndex.cpp:
+        (WebCore::IDBIndex::openCursor): Back end should never fail a request.
+        (WebCore::IDBIndex::count): Ditto.
+        (WebCore::IDBIndex::openKeyCursor): Ditto.
+        (WebCore::IDBIndex::get): Ditto.
+        (WebCore::IDBIndex::getKey): Ditto.
+        * Modules/indexeddb/IDBIndexBackendImpl.cpp:
+        (WebCore::IDBIndexBackendImpl::openCursor): Change from EC to firing error.
+        (WebCore::IDBIndexBackendImpl::openKeyCursor): Ditto.
+        (WebCore::IDBIndexBackendImpl::count): Ditto.
+        (WebCore::IDBIndexBackendImpl::get): Ditto.
+        (WebCore::IDBIndexBackendImpl::getKey): Ditto.
+        * Modules/indexeddb/IDBObjectStore.cpp:
+        (WebCore::IDBObjectStore::get): Back end should never fail a request.
+        (WebCore::IDBObjectStore::put): Ditto.
+        (WebCore::IDBObjectStore::deleteFunction): Ditto.
+        (WebCore::IDBObjectStore::clear): Ditto.
+        (WebCore): Ditto.
+        (WebCore::IDBObjectStore::openCursor): Ditto.
+        (WebCore::IDBObjectStore::count): Ditto.
+        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
+        (WebCore::IDBObjectStoreBackendImpl::get): Change from EC to firing error.
+        (WebCore::IDBObjectStoreBackendImpl::putWithIndexKeys): Ditto.
+        (WebCore):
+        (WebCore::IDBObjectStoreBackendImpl::deleteFunction): Ditto.
+        (WebCore::IDBObjectStoreBackendImpl::clear): Ditto.
+        (WebCore::IDBObjectStoreBackendImpl::openCursor): Ditto.
+        (WebCore::IDBObjectStoreBackendImpl::count): Ditto.
+
 2012-10-01  Ryosuke Niwa  <rn...@webkit.org>
 
         Build fix. Clearly, these objects could be instantiated in worker threads.

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp	2012-10-01 23:14:13 UTC (rev 130095)
@@ -176,8 +176,7 @@
     m_request->setPendingCursor(this);
     m_gotValue = false;
     m_backend->advance(count, m_request, ec);
-    if (ec)
-        m_request->markEarlyDeath();
+    ASSERT(!ec);
 }
 
 void IDBCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionCode& ec)
@@ -218,8 +217,7 @@
     m_request->setPendingCursor(this);
     m_gotValue = false;
     m_backend->continueFunction(key, m_request, ec);
-    if (ec)
-        m_request->markEarlyDeath();
+    ASSERT(!ec);
 }
 
 PassRefPtr<IDBRequest> IDBCursor::deleteFunction(ScriptExecutionContext* context, ExceptionCode& ec)
@@ -234,16 +232,13 @@
         return 0;
     }
 
-    if (!m_gotValue) {
+    if (!m_gotValue || isKeyCursor()) {
         ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
         return 0;
     }
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     m_backend->deleteFunction(request, ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request.release();
 }
 

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp	2012-10-01 23:14:13 UTC (rev 130095)
@@ -63,20 +63,22 @@
     m_objectStore.clear();
 }
 
-void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
+void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode&)
 {
     IDB_TRACE("IDBCursorBackendImpl::continue");
+    RefPtr<IDBCallbacks> callbacks = prpCallbacks;
 
-    if (!m_transaction->scheduleTask(m_taskType, createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, this, prpKey, prpCallbacks)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+    if (!m_transaction->scheduleTask(m_taskType, createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, this, prpKey, callbacks)))
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
-void IDBCursorBackendImpl::advance(unsigned long count, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
+void IDBCursorBackendImpl::advance(unsigned long count, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode&)
 {
     IDB_TRACE("IDBCursorBackendImpl::advance");
+    RefPtr<IDBCallbacks> callbacks = prpCallbacks;
 
-    if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::advanceInternal, this, count, prpCallbacks)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+    if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::advanceInternal, this, count, callbacks)))
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 void IDBCursorBackendImpl::advanceInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> prpCursor, unsigned long count, PassRefPtr<IDBCallbacks> callbacks)
@@ -107,27 +109,25 @@
     callbacks->onSuccess(cursor->key(), cursor->primaryKey(), cursor->value());
 }
 
-void IDBCursorBackendImpl::deleteFunction(PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
+void IDBCursorBackendImpl::deleteFunction(PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode&)
 {
     IDB_TRACE("IDBCursorBackendImpl::delete");
     ASSERT(m_transaction->mode() != IDBTransaction::READ_ONLY);
 
-    if (!m_cursor || m_cursorType == IndexKeyCursor) {
-        ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
-        return;
-    }
-
+    ExceptionCode ec = 0;
     RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(m_cursor->primaryKey(), ec);
     ASSERT(!ec);
 
     m_objectStore->deleteFunction(keyRange.release(), prpCallbacks, m_transaction.get(), ec);
+    ASSERT(!ec);
 }
 
-void IDBCursorBackendImpl::prefetchContinue(int numberToFetch, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
+void IDBCursorBackendImpl::prefetchContinue(int numberToFetch, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode&)
 {
     IDB_TRACE("IDBCursorBackendImpl::prefetchContinue");
-    if (!m_transaction->scheduleTask(m_taskType, createCallbackTask(&IDBCursorBackendImpl::prefetchContinueInternal, this, numberToFetch, prpCallbacks)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+    RefPtr<IDBCallbacks> callbacks = prpCallbacks;
+    if (!m_transaction->scheduleTask(m_taskType, createCallbackTask(&IDBCursorBackendImpl::prefetchContinueInternal, this, numberToFetch, callbacks)))
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 void IDBCursorBackendImpl::prefetchContinueInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> prpCursor, int numberToFetch, PassRefPtr<IDBCallbacks> callbacks)

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseError.h (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseError.h	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseError.h	2012-10-01 23:14:13 UTC (rev 130095)
@@ -37,6 +37,13 @@
 
 class IDBDatabaseError : public RefCounted<IDBDatabaseError> {
 public:
+    static PassRefPtr<IDBDatabaseError> create(unsigned short code)
+    {
+        ASSERT(code >= IDBDatabaseException::IDBDatabaseExceptionOffset);
+        ASSERT(code < IDBDatabaseException::IDBDatabaseExceptionMax);
+        return adoptRef(new IDBDatabaseError(code));
+    }
+
     static PassRefPtr<IDBDatabaseError> create(unsigned short code, const String& message)
     {
         ASSERT(code >= IDBDatabaseException::IDBDatabaseExceptionOffset);
@@ -52,8 +59,10 @@
     const String name() const { return IDBDatabaseException::getErrorName(m_code); };
 
 private:
+    IDBDatabaseError(unsigned short code)
+        : m_code(code), m_message(IDBDatabaseException::getErrorDescription(code)) { }
     IDBDatabaseError(unsigned short code, const String& message)
-            : m_code(code), m_message(message) { }
+        : m_code(code), m_message(message) { }
 
     const unsigned short m_code;
     const String m_message;

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseException.cpp (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseException.cpp	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseException.cpp	2012-10-01 23:14:13 UTC (rev 130095)
@@ -103,6 +103,16 @@
     return entry->name;
 }
 
+String IDBDatabaseException::getErrorDescription(ExceptionCode ec)
+{
+    const IDBDatabaseExceptionNameDescription* entry = getErrorEntry(ec);
+    ASSERT(entry);
+    if (!entry)
+        return "Unknown error.";
+
+    return entry->description;
+}
+
 ExceptionCode IDBDatabaseException::getLegacyErrorCode(ExceptionCode ec)
 {
     const IDBDatabaseExceptionNameDescription* entry = getErrorEntry(ec);

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseException.h (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseException.h	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseException.h	2012-10-01 23:14:13 UTC (rev 130095)
@@ -78,6 +78,7 @@
 
     static bool initializeDescription(ExceptionCode, ExceptionCodeDescription*);
     static String getErrorName(ExceptionCode);
+    static String getErrorDescription(ExceptionCode);
     static ExceptionCode getLegacyErrorCode(ExceptionCode);
 
 private:

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp	2012-10-01 23:14:13 UTC (rev 130095)
@@ -77,10 +77,7 @@
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     request->setCursorDetails(IDBCursorBackendInterface::IndexCursor, direction);
     m_backend->openCursor(keyRange, direction, request, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request;
 }
 
@@ -127,10 +124,7 @@
     }
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     m_backend->count(keyRange, request, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request;
 }
 
@@ -161,10 +155,7 @@
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     request->setCursorDetails(IDBCursorBackendInterface::IndexKeyCursor, direction);
     m_backend->openKeyCursor(keyRange, direction, request, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request;
 }
 
@@ -225,10 +216,7 @@
 
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     m_backend->get(keyRange, request, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request;
 }
 
@@ -260,10 +248,7 @@
 
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     m_backend->getKey(keyRange, request, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request;
 }
 

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp	2012-10-01 23:14:13 UTC (rev 130095)
@@ -103,7 +103,7 @@
     callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
 }
 
-void IDBIndexBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpKeyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBIndexBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpKeyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBIndexBackendImpl::openCursor");
     RefPtr<IDBIndexBackendImpl> index = this;
@@ -112,10 +112,10 @@
     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
     if (!transaction->scheduleTask(
             createCallbackTask(&openCursorInternal, index, keyRange, direction, IDBCursorBackendInterface::IndexCursor, callbacks, transaction)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
-void IDBIndexBackendImpl::openKeyCursor(PassRefPtr<IDBKeyRange> prpKeyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBIndexBackendImpl::openKeyCursor(PassRefPtr<IDBKeyRange> prpKeyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBIndexBackendImpl::openKeyCursor");
     RefPtr<IDBIndexBackendImpl> index = this;
@@ -124,7 +124,7 @@
     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
     if (!transaction->scheduleTask(
             createCallbackTask(&openCursorInternal, index, keyRange, direction, IDBCursorBackendInterface::IndexKeyCursor, callbacks, transaction)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 void IDBIndexBackendImpl::countInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction)
@@ -145,13 +145,13 @@
     callbacks->onSuccess(SerializedScriptValue::numberValue(count));
 }
 
-void IDBIndexBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBIndexBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBIndexBackendImpl::count");
     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
     if (!transaction->scheduleTask(
             createCallbackTask(&countInternal, this, range, callbacks, transaction)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 void IDBIndexBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction)
@@ -212,7 +212,7 @@
 }
 
 
-void IDBIndexBackendImpl::get(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBIndexBackendImpl::get(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBIndexBackendImpl::get");
     RefPtr<IDBIndexBackendImpl> index = this;
@@ -220,10 +220,10 @@
     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
     if (!transaction->scheduleTask(createCallbackTask(&getInternal, index, keyRange, callbacks, transaction)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
-void IDBIndexBackendImpl::getKey(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBIndexBackendImpl::getKey(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBIndexBackendImpl::getKey");
     RefPtr<IDBIndexBackendImpl> index = this;
@@ -232,7 +232,7 @@
     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
     if (!transaction->scheduleTask(
             createCallbackTask(&getKeyInternal, index, keyRange, callbacks, transaction)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp	2012-10-01 23:14:13 UTC (rev 130095)
@@ -88,10 +88,7 @@
     }
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     m_backend->get(keyRange, request, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request.release();
 }
 
@@ -219,10 +216,7 @@
 
     RefPtr<IDBRequest> request = IDBRequest::create(context, source, m_transaction.get());
     m_backend->putWithIndexKeys(serializedValue.release(), key.release(), putMode, request, m_transaction->backend(), indexNames, indexKeys, ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request.release();
 }
 
@@ -248,10 +242,7 @@
 
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     m_backend->deleteFunction(keyRange, request, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request.release();
 }
 
@@ -282,10 +273,7 @@
 
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     m_backend->clear(request, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request.release();
 }
 
@@ -514,10 +502,7 @@
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     request->setCursorDetails(IDBCursorBackendInterface::ObjectStoreCursor, direction);
     m_backend->openCursor(range, direction, request, taskType, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request.release();
 }
 
@@ -564,10 +549,7 @@
     }
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
     m_backend->count(range, request, m_transaction->backend(), ec);
-    if (ec) {
-        request->markEarlyDeath();
-        return 0;
-    }
+    ASSERT(!ec);
     return request.release();
 }
 

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp	2012-10-01 23:14:13 UTC (rev 130095)
@@ -78,7 +78,7 @@
     return metadata;
 }
 
-void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBObjectStoreBackendImpl::get");
     RefPtr<IDBObjectStoreBackendImpl> objectStore = this;
@@ -87,7 +87,7 @@
     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
     if (!transaction->scheduleTask(
             createCallbackTask(&IDBObjectStoreBackendImpl::getInternal, objectStore, keyRange, callbacks, transaction)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 void IDBObjectStoreBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction)
@@ -120,7 +120,7 @@
     callbacks->onSuccess(SerializedScriptValue::createFromWire(wireData));
 }
 
-void IDBObjectStoreBackendImpl::putWithIndexKeys(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, const Vector<String>& indexNames, const Vector<IndexKeys>& indexKeys, ExceptionCode& ec)
+void IDBObjectStoreBackendImpl::putWithIndexKeys(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, const Vector<String>& indexNames, const Vector<IndexKeys>& indexKeys, ExceptionCode&)
 {
     IDB_TRACE("IDBObjectStoreBackendImpl::putWithIndexKeys");
 
@@ -138,7 +138,7 @@
 
     if (!transaction->scheduleTask(
             createCallbackTask(&IDBObjectStoreBackendImpl::putInternal, objectStore, value, key, putMode, callbacks, transaction, newIndexNames.release(), newIndexKeys.release())))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 namespace {
@@ -368,7 +368,7 @@
     callbacks->onSuccess(key.release());
 }
 
-void IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBObjectStoreBackendImpl::delete");
 
@@ -381,7 +381,7 @@
 
     if (!transaction->scheduleTask(
             createCallbackTask(&IDBObjectStoreBackendImpl::deleteInternal, objectStore, keyRange, callbacks, transaction)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 void IDBObjectStoreBackendImpl::deleteInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction)
@@ -413,7 +413,7 @@
     callbacks->onSuccess(SerializedScriptValue::undefinedValue());
 }
 
-void IDBObjectStoreBackendImpl::clear(PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBObjectStoreBackendImpl::clear(PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBObjectStoreBackendImpl::clear");
 
@@ -425,7 +425,7 @@
 
     if (!transaction->scheduleTask(
             createCallbackTask(&IDBObjectStoreBackendImpl::clearInternal, objectStore, callbacks, transaction)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 void IDBObjectStoreBackendImpl::clearInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction)
@@ -503,7 +503,7 @@
     transaction->didCompleteTaskEvents();
 }
 
-void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBObjectStoreBackendImpl::openCursor");
     RefPtr<IDBObjectStoreBackendImpl> objectStore = this;
@@ -512,7 +512,7 @@
     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
     if (!transaction->scheduleTask(
             createCallbackTask(&IDBObjectStoreBackendImpl::openCursorInternal, objectStore, range, direction, callbacks, taskType, transaction))) {
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
     }
 }
 
@@ -536,13 +536,13 @@
     callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
 }
 
-void IDBObjectStoreBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+void IDBObjectStoreBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
 {
     IDB_TRACE("IDBObjectStoreBackendImpl::count");
     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
     if (!transaction->scheduleTask(
             createCallbackTask(&IDBObjectStoreBackendImpl::countInternal, this, range, callbacks, transaction)))
-        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
 }
 
 void IDBObjectStoreBackendImpl::countInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction)

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp (130094 => 130095)


--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp	2012-10-01 23:14:13 UTC (rev 130095)
@@ -174,7 +174,7 @@
     m_error.clear();
     m_errorMessage = String();
     m_result.clear();
-    onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR, "The transaction was aborted, so the request cannot be fulfilled."));
+    onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR));
     m_requestAborted = true;
 }
 

Modified: trunk/Source/WebKit/chromium/ChangeLog (130094 => 130095)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-10-01 23:14:13 UTC (rev 130095)
@@ -1,3 +1,13 @@
+2012-10-01  Joshua Bell  <jsb...@chromium.org>
+
+        IndexedDB: Move onSuccess(IDBDatabaseBackendInterface) to IDBOpenDBRequest
+        https://bugs.webkit.org/show_bug.cgi?id=94757
+
+        Reviewed by Tony Chang.
+
+        * tests/IDBRequestTest.cpp: Ensure IDBRequest can handle Error after abort.
+        (WebCore::TEST): Added AbortAfter
+
 2012-10-01  Ilya Tikhonovsky  <loi...@chromium.org>
 
         Unreviewed single line compilation fix for Canary Debug Mac.

Modified: trunk/Source/WebKit/chromium/tests/IDBRequestTest.cpp (130094 => 130095)


--- trunk/Source/WebKit/chromium/tests/IDBRequestTest.cpp	2012-10-01 23:14:02 UTC (rev 130094)
+++ trunk/Source/WebKit/chromium/tests/IDBRequestTest.cpp	2012-10-01 23:14:13 UTC (rev 130095)
@@ -58,6 +58,21 @@
     request->onSuccess(IDBKey::createInvalid(), IDBKey::createInvalid(), SerializedScriptValue::nullValue());
 }
 
+TEST(IDBRequestTest, AbortErrorAfterAbort)
+{
+    ScriptExecutionContext* context = 0;
+    IDBTransaction* transaction = 0;
+    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::createInvalid(), transaction);
+    EXPECT_EQ(request->readyState(), "pending");
+
+    // Simulate the IDBTransaction having received onAbort from back end and aborting the request:
+    request->abort();
+
+    // Now simulate the back end having fired an abort error at the request to clear up any intermediaries.
+    // Ensure an assertion is not raised.
+    request->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR, "Description goes here."));
+}
+
 } // namespace
 
 #endif // ENABLE(INDEXED_DATABASE)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to