Commit 2fd9bcf6 authored by beidson@apple.com's avatar beidson@apple.com

The IDB backing store put() method shouldn't call IDB callbacks directly

https://bugs.webkit.org/show_bug.cgi?id=127399

Reviewed by Beth Dakin.

Source/WebCore:

Refactor the put() callback to take a resulting key or an error.
* Modules/indexeddb/IDBServerConnection.h:

* Modules/indexeddb/IDBTransactionBackendOperations.cpp:
(WebCore::PutOperation::perform): Call to the backing store, then perform the
  appropriate IDB callback whether a key or an error was returned.
* Modules/indexeddb/IDBTransactionBackendOperations.h:

* Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp:
(WebCore::IDBServerConnectionLevelDB::put): Don’t call IDB callbacks directly.
  Instead, pass the resulting key/error back to the PutOperation.
* Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h:

Source/WebKit2:

* WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
(WebKit::WebIDBServerConnection::put):
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@162501 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 08316f74
2014-01-21 Brady Eidson <beidson@apple.com>
The IDB backing store put() method shouldn't call IDB callbacks directly
https://bugs.webkit.org/show_bug.cgi?id=127399
Reviewed by Beth Dakin.
Refactor the put() callback to take a resulting key or an error.
* Modules/indexeddb/IDBServerConnection.h:
* Modules/indexeddb/IDBTransactionBackendOperations.cpp:
(WebCore::PutOperation::perform): Call to the backing store, then perform the
appropriate IDB callback whether a key or an error was returned.
* Modules/indexeddb/IDBTransactionBackendOperations.h:
* Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp:
(WebCore::IDBServerConnectionLevelDB::put): Don’t call IDB callbacks directly.
Instead, pass the resulting key/error back to the PutOperation.
* Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h:
2014-01-21 Jae Hyun Park <jae.park@company100.net>
Use nullptr in HTMLCanvasElement
......@@ -78,7 +78,7 @@ public:
virtual void createIndex(IDBTransactionBackend&, const CreateIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
virtual void deleteIndex(IDBTransactionBackend&, const DeleteIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
virtual void get(IDBTransactionBackend&, const GetOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
virtual void put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
virtual void put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
virtual void count(IDBTransactionBackend&, const CountOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
virtual void deleteRange(IDBTransactionBackend&, const DeleteRangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
......
......@@ -106,7 +106,15 @@ void PutOperation::perform(std::function<void()> completionCallback)
RefPtr<PutOperation> operation(this);
STANDARD_DATABASE_ERROR_CALLBACK;
m_transaction->database().serverConnection().put(*m_transaction, *this, operationCallback);
m_transaction->database().serverConnection().put(*m_transaction, *this, [this, operation, operationCallback](PassRefPtr<IDBKey> key, PassRefPtr<IDBDatabaseError> error) {
if (key) {
ASSERT(!error);
m_callbacks->onSuccess(key);
} else {
ASSERT(error);
m_callbacks->onError(error);
}
});
}
void SetIndexesReadyOperation::perform(std::function<void()> completionCallback)
......
......@@ -305,7 +305,6 @@ public:
IDBKey* key() const { return m_key.get(); }
const Vector<int64_t>& indexIDs() const { return m_indexIDs; }
const Vector<IndexKeys>& indexKeys() const { return m_indexKeys; }
IDBCallbacks* callbacks() const { return m_callbacks.get(); }
SharedBuffer* value() const { return m_value.get(); }
private:
......
......@@ -42,6 +42,11 @@
callback(arg); \
});
#define ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(callback, arg1, arg2) \
callOnMainThread([callback]() { \
callback(arg1, arg2); \
});
#define ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(callback) \
callOnMainThread([callback]() { \
callback(0); \
......@@ -347,7 +352,7 @@ void IDBServerConnectionLevelDB::get(IDBTransactionBackend& transaction, const G
ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
}
void IDBServerConnectionLevelDB::put(IDBTransactionBackend& transaction, const PutOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
void IDBServerConnectionLevelDB::put(IDBTransactionBackend& transaction, const PutOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
{
IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
ASSERT(backingStoreTransaction);
......@@ -359,8 +364,7 @@ void IDBServerConnectionLevelDB::put(IDBTransactionBackend& transaction, const P
RefPtr<IDBKey> autoIncKey = m_backingStore->generateKey(transaction, transaction.database().id(), operation.objectStore().id);
keyWasGenerated = true;
if (!autoIncKey->isValid()) {
operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Maximum key generator value reached."));
ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Maximum key generator value reached."));
return;
}
key = autoIncKey;
......@@ -374,13 +378,11 @@ void IDBServerConnectionLevelDB::put(IDBTransactionBackend& transaction, const P
if (operation.putMode() == IDBDatabaseBackend::AddOnly) {
bool ok = m_backingStore->keyExistsInObjectStore(*backingStoreTransaction, transaction.database().id(), operation.objectStore().id, *key, recordIdentifier);
if (!ok) {
operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error checking key existence."));
ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error checking key existence."));
return;
}
if (recordIdentifier) {
operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Key already exists in the object store."));
ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Key already exists in the object store."));
return;
}
}
......@@ -390,21 +392,20 @@ void IDBServerConnectionLevelDB::put(IDBTransactionBackend& transaction, const P
bool obeysConstraints = false;
bool backingStoreSuccess = m_backingStore->makeIndexWriters(transaction.id(), transaction.database().id(), operation.objectStore(), *key, keyWasGenerated, operation.indexIDs(), operation.indexKeys(), indexWriters, &errorMessage, obeysConstraints);
if (!backingStoreSuccess) {
operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
return;
}
if (!obeysConstraints) {
operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));
ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
callOnMainThread([completionCallback, errorMessage]() { \
completionCallback(nullptr, IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage)); \
});
return;
}
// Before this point, don't do any mutation. After this point, rollback the transaction in case of error.
backingStoreSuccess = m_backingStore->putRecord(*backingStoreTransaction, transaction.database().id(), operation.objectStore().id, *key, operation.value(), recordIdentifier.get());
if (!backingStoreSuccess) {
operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add."));
ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add."));
return;
}
......@@ -416,14 +417,14 @@ void IDBServerConnectionLevelDB::put(IDBTransactionBackend& transaction, const P
if (operation.objectStore().autoIncrement && operation.putMode() != IDBDatabaseBackend::CursorUpdate && key->type() == IDBKey::NumberType) {
bool ok = m_backingStore->updateKeyGenerator(transaction, transaction.database().id(), operation.objectStore().id, *key, !keyWasGenerated);
if (!ok) {
operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error updating key generator."));
ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error updating key generator."));
return;
}
}
operation.callbacks()->onSuccess(key.release());
ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
callOnMainThread([completionCallback, key]() { \
completionCallback(key.get(), nullptr); \
});
}
void IDBServerConnectionLevelDB::openCursor(IDBTransactionBackend& transaction, const OpenCursorOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
......
......@@ -67,7 +67,7 @@ public:
virtual void createIndex(IDBTransactionBackend&, const CreateIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
virtual void deleteIndex(IDBTransactionBackend&, const DeleteIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
virtual void get(IDBTransactionBackend&, const GetOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
virtual void put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
virtual void put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
virtual void count(IDBTransactionBackend&, const CountOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
virtual void deleteRange(IDBTransactionBackend&, const DeleteRangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
......
2014-01-21 Brady Eidson <beidson@apple.com>
The IDB backing store put() method shouldn't call IDB callbacks directly
https://bugs.webkit.org/show_bug.cgi?id=127399
Reviewed by Beth Dakin.
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
(WebKit::WebIDBServerConnection::put):
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:
2014-01-21 Anders Carlsson <andersca@apple.com>
Fix 32-bit build.
......
......@@ -300,7 +300,7 @@ void WebIDBServerConnection::get(IDBTransactionBackend&, const GetOperation&, st
{
}
void WebIDBServerConnection::put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
void WebIDBServerConnection::put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
{
}
......
......@@ -67,7 +67,7 @@ public:
virtual void createIndex(WebCore::IDBTransactionBackend&, const WebCore::CreateIndexOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
virtual void deleteIndex(WebCore::IDBTransactionBackend&, const WebCore::DeleteIndexOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
virtual void get(WebCore::IDBTransactionBackend&, const WebCore::GetOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
virtual void put(WebCore::IDBTransactionBackend&, const WebCore::PutOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
virtual void put(WebCore::IDBTransactionBackend&, const WebCore::PutOperation&, std::function<void(PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
virtual void openCursor(WebCore::IDBTransactionBackend&, const WebCore::OpenCursorOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
virtual void count(WebCore::IDBTransactionBackend&, const WebCore::CountOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
virtual void deleteRange(WebCore::IDBTransactionBackend&, const WebCore::DeleteRangeOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
......
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