summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp')
-rw-r--r--Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp423
1 files changed, 44 insertions, 379 deletions
diff --git a/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp b/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp
index 244f28566..2ea93ddf2 100644
--- a/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp
+++ b/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,23 +29,19 @@
#include "config.h"
#include "SQLTransactionBackend.h"
-#if ENABLE(SQL_DATABASE)
-
-#include "AbstractSQLTransaction.h"
-#include "Database.h" // FIXME: Should only be used in the frontend.
+#include "Database.h"
#include "DatabaseAuthorizer.h"
-#include "DatabaseBackend.h"
-#include "DatabaseBackendContext.h"
+#include "DatabaseContext.h"
#include "DatabaseThread.h"
#include "DatabaseTracker.h"
-#include "ExceptionCode.h"
#include "Logging.h"
#include "OriginLock.h"
#include "SQLError.h"
-#include "SQLStatementBackend.h"
-#include "SQLTransactionClient.h"
+#include "SQLStatement.h"
+#include "SQLStatementCallback.h"
+#include "SQLStatementErrorCallback.h"
+#include "SQLTransaction.h"
#include "SQLTransactionCoordinator.h"
-#include "SQLValue.h"
#include "SQLiteTransaction.h"
#include <wtf/StdLibExtras.h>
#include <wtf/text/WTFString.h>
@@ -260,7 +256,7 @@
//
// When executing the transaction (in DatabaseThread::databaseThread()):
// ====================================================================
-// OwnPtr<DatabaseTask> task; // points to ...
+// std::unique_ptr<DatabaseTask> task; // points to ...
// --> DatabaseTransactionTask // RefPtr<SQLTransactionBackend> m_transaction points to ...
// --> SQLTransactionBackend // RefPtr<SQLTransaction> m_frontend;
// --> SQLTransaction // RefPtr<SQLTransactionBackend> m_backend points to ...
@@ -284,7 +280,7 @@
// However, there will still be a DatabaseTask pointing to the SQLTransactionBackend (see
// the "When executing the transaction" chain above). This will keep the
// SQLTransactionBackend alive until DatabaseThread::databaseThread() releases its
-// task OwnPtr.
+// task std::unique_ptr.
//
// What happens if a transaction is interrupted?
// ============================================
@@ -344,61 +340,38 @@
namespace WebCore {
-PassRefPtr<SQLTransactionBackend> SQLTransactionBackend::create(DatabaseBackend* db,
- PassRefPtr<AbstractSQLTransaction> frontend, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
-{
- return adoptRef(new SQLTransactionBackend(db, frontend, wrapper, readOnly));
-}
-
-SQLTransactionBackend::SQLTransactionBackend(DatabaseBackend* db,
- PassRefPtr<AbstractSQLTransaction> frontend, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
+SQLTransactionBackend::SQLTransactionBackend(SQLTransaction& frontend)
: m_frontend(frontend)
- , m_database(db)
- , m_wrapper(wrapper)
- , m_hasCallback(m_frontend->hasCallback())
- , m_hasSuccessCallback(m_frontend->hasSuccessCallback())
- , m_hasErrorCallback(m_frontend->hasErrorCallback())
- , m_shouldRetryCurrentStatement(false)
- , m_modifiedDatabase(false)
- , m_lockAcquired(false)
- , m_readOnly(readOnly)
- , m_hasVersionMismatch(false)
{
- ASSERT(m_database);
- m_frontend->setBackend(this);
m_requestedState = SQLTransactionState::AcquireLock;
}
SQLTransactionBackend::~SQLTransactionBackend()
{
- ASSERT(!m_sqliteTransaction);
+ ASSERT(!m_frontend.m_sqliteTransaction);
}
void SQLTransactionBackend::doCleanup()
{
- if (!m_frontend)
- return;
- m_frontend = 0; // Break the reference cycle. See comment about the life-cycle above.
-
- ASSERT(currentThread() == database()->databaseContext()->databaseThread()->getThreadID());
+ ASSERT(currentThread() == m_frontend.database().databaseThread().getThreadID());
- releaseOriginLockIfNeeded();
+ m_frontend.releaseOriginLockIfNeeded();
- MutexLocker locker(m_statementMutex);
- m_statementQueue.clear();
+ LockHolder locker(m_frontend.m_statementMutex);
+ m_frontend.m_statementQueue.clear();
- if (m_sqliteTransaction) {
+ if (m_frontend.m_sqliteTransaction) {
// In the event we got here because of an interruption or error (i.e. if
// the transaction is in progress), we should roll it back here. Clearing
// m_sqliteTransaction invokes SQLiteTransaction's destructor which does
// just that. We might as well do this unconditionally and free up its
// resources because we're already terminating.
- m_sqliteTransaction.clear();
+ m_frontend.m_sqliteTransaction = nullptr;
}
// Release the lock on this database
- if (m_lockAcquired)
- m_database->transactionCoordinator()->releaseLock(this);
+ if (m_frontend.m_lockAcquired)
+ m_frontend.m_database->transactionCoordinator()->releaseLock(m_frontend);
// Do some aggresive clean up here except for m_database.
//
@@ -423,23 +396,7 @@ void SQLTransactionBackend::doCleanup()
// SQLTransactionBackend is guaranteed to not destruct until the frontend
// is also destructing.
- m_wrapper = 0;
-}
-
-AbstractSQLStatement* SQLTransactionBackend::currentStatement()
-{
- return m_currentStatementBackend->frontend();
-}
-
-PassRefPtr<SQLError> SQLTransactionBackend::transactionError()
-{
- return m_transactionError;
-}
-
-void SQLTransactionBackend::setShouldRetryCurrentStatement(bool shouldRetry)
-{
- ASSERT(!m_shouldRetryCurrentStatement);
- m_shouldRetryCurrentStatement = shouldRetry;
+ m_frontend.m_wrapper = nullptr;
}
SQLTransactionBackend::StateFunction SQLTransactionBackend::stateFunctionFor(SQLTransactionState state)
@@ -450,14 +407,14 @@ SQLTransactionBackend::StateFunction SQLTransactionBackend::stateFunctionFor(SQL
&SQLTransactionBackend::acquireLock, // 2.
&SQLTransactionBackend::openTransactionAndPreflight, // 3.
&SQLTransactionBackend::runStatements, // 4.
- &SQLTransactionBackend::postflightAndCommit, // 5.
+ &SQLTransactionBackend::unreachableState, // 5. postflightAndCommit
&SQLTransactionBackend::cleanupAndTerminate, // 6.
&SQLTransactionBackend::cleanupAfterTransactionErrorCallback, // 7.
- &SQLTransactionBackend::sendToFrontendState, // 8. deliverTransactionCallback
- &SQLTransactionBackend::sendToFrontendState, // 9. deliverTransactionErrorCallback
- &SQLTransactionBackend::sendToFrontendState, // 10. deliverStatementCallback
- &SQLTransactionBackend::sendToFrontendState, // 11. deliverQuotaIncreaseCallback
- &SQLTransactionBackend::sendToFrontendState // 12. deliverSuccessCallback
+ &SQLTransactionBackend::unreachableState, // 8. deliverTransactionCallback
+ &SQLTransactionBackend::unreachableState, // 9. deliverTransactionErrorCallback
+ &SQLTransactionBackend::unreachableState, // 10. deliverStatementCallback
+ &SQLTransactionBackend::unreachableState, // 11. deliverQuotaIncreaseCallback
+ &SQLTransactionBackend::unreachableState // 12. deliverSuccessCallback
};
ASSERT(WTF_ARRAY_LENGTH(stateFunctions) == static_cast<int>(SQLTransactionState::NumberOfStates));
@@ -466,17 +423,11 @@ SQLTransactionBackend::StateFunction SQLTransactionBackend::stateFunctionFor(SQL
return stateFunctions[static_cast<int>(state)];
}
-void SQLTransactionBackend::enqueueStatementBackend(PassRefPtr<SQLStatementBackend> statementBackend)
-{
- MutexLocker locker(m_statementMutex);
- m_statementQueue.append(statementBackend);
-}
-
void SQLTransactionBackend::computeNextStateAndCleanupIfNeeded()
{
// Only honor the requested state transition if we're not supposed to be
// cleaning up and shutting down:
- if (m_database->opened() && !m_database->isInterrupted()) {
+ if (m_frontend.m_database->opened()) {
setStateToRequestedState();
ASSERT(m_nextState == SQLTransactionState::AcquireLock
|| m_nextState == SQLTransactionState::OpenTransactionAndPreflight
@@ -498,49 +449,23 @@ void SQLTransactionBackend::computeNextStateAndCleanupIfNeeded()
LOG(StorageAPI, "Database was stopped or interrupted - cancelling work for this transaction");
// The current SQLite transaction should be stopped, as well
- if (m_sqliteTransaction) {
- m_sqliteTransaction->stop();
- m_sqliteTransaction.clear();
+ if (m_frontend.m_sqliteTransaction) {
+ m_frontend.m_sqliteTransaction->stop();
+ m_frontend.m_sqliteTransaction = nullptr;
}
// Terminate the frontend state machine. This also gets the frontend to
// call computeNextStateAndCleanupIfNeeded() and clear its wrappers
// if needed.
- m_frontend->requestTransitToState(SQLTransactionState::End);
+ m_frontend.requestTransitToState(SQLTransactionState::End);
// Redirect to the end state to abort, clean up, and end the transaction.
doCleanup();
}
-void SQLTransactionBackend::performNextStep()
-{
- computeNextStateAndCleanupIfNeeded();
- runStateMachine();
-}
-
-#if PLATFORM(IOS)
-bool SQLTransactionBackend::shouldPerformWhilePaused() const
-{
- // SQLTransactions should only run-while-paused if they have progressed passed the first transaction step.
- return m_nextState != SQLTransactionState::AcquireLock;
-}
-#endif
-
-void SQLTransactionBackend::executeSQL(PassOwnPtr<AbstractSQLStatement> statement,
- const String& sqlStatement, const Vector<SQLValue>& arguments, int permissions)
-{
- RefPtr<SQLStatementBackend> statementBackend;
- statementBackend = SQLStatementBackend::create(statement, sqlStatement, arguments, permissions);
-
- if (Database::from(m_database.get())->deleted())
- statementBackend->setDatabaseDeletedError();
-
- enqueueStatementBackend(statementBackend);
-}
-
void SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown()
{
- ASSERT(currentThread() == database()->databaseContext()->databaseThread()->getThreadID());
+ ASSERT(currentThread() == m_frontend.database().databaseThread().getThreadID());
// If the transaction is in progress, we should roll it back here, since this
// is our last opportunity to do something related to this transaction on the
@@ -550,264 +475,29 @@ void SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown()
doCleanup();
}
-SQLTransactionState SQLTransactionBackend::acquireLock()
-{
- m_database->transactionCoordinator()->acquireLock(this);
- return SQLTransactionState::Idle;
-}
-
-void SQLTransactionBackend::lockAcquired()
-{
- m_lockAcquired = true;
- requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight);
-}
-
-SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight()
-{
- ASSERT(!m_database->sqliteDatabase().transactionInProgress());
- ASSERT(m_lockAcquired);
-
- LOG(StorageAPI, "Opening and preflighting transaction %p", this);
-
- // If the database was deleted, jump to the error callback
- if (Database::from(m_database.get())->deleted()) {
- m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unable to open a transaction, because the user deleted the database");
- return nextStateForTransactionError();
- }
-
- // Set the maximum usage for this transaction if this transactions is not read-only
- if (!m_readOnly) {
- acquireOriginLock();
- m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize());
- }
-
- ASSERT(!m_sqliteTransaction);
- m_sqliteTransaction = adoptPtr(new SQLiteTransaction(m_database->sqliteDatabase(), m_readOnly));
-
- m_database->resetDeletes();
- m_database->disableAuthorizer();
- m_sqliteTransaction->begin();
- m_database->enableAuthorizer();
-
- // Spec 4.3.2.1+2: Open a transaction to the database, jumping to the error callback if that fails
- if (!m_sqliteTransaction->inProgress()) {
- ASSERT(!m_database->sqliteDatabase().transactionInProgress());
- m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to begin transaction",
- m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg());
- m_sqliteTransaction.clear();
- return nextStateForTransactionError();
- }
-
- // Note: We intentionally retrieve the actual version even with an empty expected version.
- // In multi-process browsers, we take this opportinutiy to update the cached value for
- // the actual version. In single-process browsers, this is just a map lookup.
- String actualVersion;
- if (!m_database->getActualVersionForTransaction(actualVersion)) {
- m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to read version",
- m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg());
- m_database->disableAuthorizer();
- m_sqliteTransaction.clear();
- m_database->enableAuthorizer();
- return nextStateForTransactionError();
- }
- m_hasVersionMismatch = !m_database->expectedVersion().isEmpty() && (m_database->expectedVersion() != actualVersion);
-
- // Spec 4.3.2.3: Perform preflight steps, jumping to the error callback if they fail
- if (m_wrapper && !m_wrapper->performPreflight(this)) {
- m_database->disableAuthorizer();
- m_sqliteTransaction.clear();
- m_database->enableAuthorizer();
- m_transactionError = m_wrapper->sqlError();
- if (!m_transactionError)
- m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction preflight");
- return nextStateForTransactionError();
- }
-
- // Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction object
- if (m_hasCallback)
- return SQLTransactionState::DeliverTransactionCallback;
-
- // If we have no callback to make, skip pass to the state after:
- return SQLTransactionState::RunStatements;
-}
-
-SQLTransactionState SQLTransactionBackend::runStatements()
+void SQLTransactionBackend::acquireLock()
{
- ASSERT(m_lockAcquired);
- SQLTransactionState nextState;
-
- // If there is a series of statements queued up that are all successful and have no associated
- // SQLStatementCallback objects, then we can burn through the queue
- do {
- if (m_shouldRetryCurrentStatement && !m_sqliteTransaction->wasRolledBackBySqlite()) {
- m_shouldRetryCurrentStatement = false;
- // FIXME - Another place that needs fixing up after <rdar://problem/5628468> is addressed.
- // See ::openTransactionAndPreflight() for discussion
-
- // Reset the maximum size here, as it was increased to allow us to retry this statement.
- // m_shouldRetryCurrentStatement is set to true only when a statement exceeds
- // the quota, which can happen only in a read-write transaction. Therefore, there
- // is no need to check here if the transaction is read-write.
- m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize());
- } else {
- // If the current statement has already been run, failed due to quota constraints, and we're not retrying it,
- // that means it ended in an error. Handle it now
- if (m_currentStatementBackend && m_currentStatementBackend->lastExecutionFailedDueToQuota()) {
- return nextStateForCurrentStatementError();
- }
-
- // Otherwise, advance to the next statement
- getNextStatement();
- }
- nextState = runCurrentStatementAndGetNextState();
- } while (nextState == SQLTransactionState::RunStatements);
-
- return nextState;
+ m_frontend.acquireLock();
}
-void SQLTransactionBackend::getNextStatement()
+void SQLTransactionBackend::openTransactionAndPreflight()
{
- m_currentStatementBackend = 0;
-
- MutexLocker locker(m_statementMutex);
- if (!m_statementQueue.isEmpty())
- m_currentStatementBackend = m_statementQueue.takeFirst();
-}
-
-SQLTransactionState SQLTransactionBackend::runCurrentStatementAndGetNextState()
-{
- if (!m_currentStatementBackend) {
- // No more statements to run. So move on to the next state.
- return SQLTransactionState::PostflightAndCommit;
- }
-
- m_database->resetAuthorizer();
-
- if (m_hasVersionMismatch)
- m_currentStatementBackend->setVersionMismatchedError();
-
- if (m_currentStatementBackend->execute(m_database.get())) {
- if (m_database->lastActionChangedDatabase()) {
- // Flag this transaction as having changed the database for later delegate notification
- m_modifiedDatabase = true;
- }
-
- if (m_currentStatementBackend->hasStatementCallback()) {
- return SQLTransactionState::DeliverStatementCallback;
- }
-
- // If we get here, then the statement doesn't have a callback to invoke.
- // We can move on to the next statement. Hence, stay in this state.
- return SQLTransactionState::RunStatements;
- }
-
- if (m_currentStatementBackend->lastExecutionFailedDueToQuota()) {
- return SQLTransactionState::DeliverQuotaIncreaseCallback;
- }
-
- return nextStateForCurrentStatementError();
-}
-
-SQLTransactionState SQLTransactionBackend::nextStateForCurrentStatementError()
-{
- // Spec 4.3.2.6.6: error - Call the statement's error callback, but if there was no error callback,
- // or the transaction was rolled back, jump to the transaction error callback
- if (m_currentStatementBackend->hasStatementErrorCallback() && !m_sqliteTransaction->wasRolledBackBySqlite())
- return SQLTransactionState::DeliverStatementCallback;
-
- m_transactionError = m_currentStatementBackend->sqlError();
- if (!m_transactionError)
- m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "the statement failed to execute");
- return nextStateForTransactionError();
-}
-
-SQLTransactionState SQLTransactionBackend::postflightAndCommit()
-{
- ASSERT(m_lockAcquired);
-
- // Spec 4.3.2.7: Perform postflight steps, jumping to the error callback if they fail.
- if (m_wrapper && !m_wrapper->performPostflight(this)) {
- m_transactionError = m_wrapper->sqlError();
- if (!m_transactionError)
- m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction postflight");
- return nextStateForTransactionError();
- }
-
- // Spec 4.3.2.7: Commit the transaction, jumping to the error callback if that fails.
- ASSERT(m_sqliteTransaction);
-
- m_database->disableAuthorizer();
- m_sqliteTransaction->commit();
- m_database->enableAuthorizer();
-
- releaseOriginLockIfNeeded();
-
- // If the commit failed, the transaction will still be marked as "in progress"
- if (m_sqliteTransaction->inProgress()) {
- if (m_wrapper)
- m_wrapper->handleCommitFailedAfterPostflight(this);
- m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to commit transaction",
- m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg());
- return nextStateForTransactionError();
- }
-
- // Vacuum the database if anything was deleted.
- if (m_database->hadDeletes())
- m_database->incrementalVacuumIfNeeded();
-
- // The commit was successful. If the transaction modified this database, notify the delegates.
- if (m_modifiedDatabase)
- m_database->transactionClient()->didCommitWriteTransaction(database());
-
- // Spec 4.3.2.8: Deliver success callback, if there is one.
- return SQLTransactionState::DeliverSuccessCallback;
+ m_frontend.openTransactionAndPreflight();
}
-SQLTransactionState SQLTransactionBackend::cleanupAndTerminate()
+void SQLTransactionBackend::runStatements()
{
- ASSERT(m_lockAcquired);
-
- // Spec 4.3.2.9: End transaction steps. There is no next step.
- LOG(StorageAPI, "Transaction %p is complete\n", this);
- ASSERT(!m_database->sqliteDatabase().transactionInProgress());
-
- // Phase 5 cleanup. See comment on the SQLTransaction life-cycle above.
- doCleanup();
- m_database->inProgressTransactionCompleted();
- return SQLTransactionState::End;
+ m_frontend.runStatements();
}
-SQLTransactionState SQLTransactionBackend::nextStateForTransactionError()
+void SQLTransactionBackend::cleanupAndTerminate()
{
- ASSERT(m_transactionError);
- if (m_hasErrorCallback)
- return SQLTransactionState::DeliverTransactionErrorCallback;
-
- // No error callback, so fast-forward to the next state and rollback the
- // transaction.
- return SQLTransactionState::CleanupAfterTransactionErrorCallback;
+ m_frontend.cleanupAndTerminate();
}
-SQLTransactionState SQLTransactionBackend::cleanupAfterTransactionErrorCallback()
+void SQLTransactionBackend::cleanupAfterTransactionErrorCallback()
{
- ASSERT(m_lockAcquired);
-
- LOG(StorageAPI, "Transaction %p is complete with an error\n", this);
- m_database->disableAuthorizer();
- if (m_sqliteTransaction) {
- // Spec 4.3.2.10: Rollback the transaction.
- m_sqliteTransaction->rollback();
-
- ASSERT(!m_database->sqliteDatabase().transactionInProgress());
- m_sqliteTransaction.clear();
- }
- m_database->enableAuthorizer();
-
- releaseOriginLockIfNeeded();
-
- ASSERT(!m_database->sqliteDatabase().transactionInProgress());
-
- return SQLTransactionState::CleanupAndTerminate;
+ m_frontend.cleanupAfterTransactionErrorCallback();
}
// requestTransitToState() can be called from the frontend. Hence, it should
@@ -818,40 +508,15 @@ void SQLTransactionBackend::requestTransitToState(SQLTransactionState nextState)
LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this);
m_requestedState = nextState;
ASSERT(m_requestedState != SQLTransactionState::End);
- m_database->scheduleTransactionStep(this);
+ m_frontend.m_database->scheduleTransactionStep(m_frontend);
}
// This state function is used as a stub function to plug unimplemented states
// in the state dispatch table. They are unimplemented because they should
// never be reached in the course of correct execution.
-SQLTransactionState SQLTransactionBackend::unreachableState()
+void SQLTransactionBackend::unreachableState()
{
ASSERT_NOT_REACHED();
- return SQLTransactionState::End;
-}
-
-SQLTransactionState SQLTransactionBackend::sendToFrontendState()
-{
- ASSERT(m_nextState != SQLTransactionState::Idle);
- m_frontend->requestTransitToState(m_nextState);
- return SQLTransactionState::Idle;
-}
-
-void SQLTransactionBackend::acquireOriginLock()
-{
- ASSERT(!m_originLock);
- m_originLock = DatabaseTracker::tracker().originLockFor(m_database->securityOrigin());
- m_originLock->lock();
-}
-
-void SQLTransactionBackend::releaseOriginLockIfNeeded()
-{
- if (m_originLock) {
- m_originLock->unlock();
- m_originLock.clear();
- }
}
} // namespace WebCore
-
-#endif // ENABLE(SQL_DATABASE)