Modified: trunk/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp (188174 => 188175)
--- trunk/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp 2015-08-07 23:31:36 UTC (rev 188174)
+++ trunk/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp 2015-08-07 23:39:53 UTC (rev 188175)
@@ -447,14 +447,14 @@
&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));
@@ -552,7 +552,10 @@
void SQLTransactionBackend::lockAcquired()
{
m_lockAcquired = true;
- requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight);
+
+ m_requestedState = SQLTransactionState::OpenTransactionAndPreflight;
+ ASSERT(m_requestedState != SQLTransactionState::End);
+ m_database->scheduleTransactionStep(this);
}
SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight()
@@ -565,7 +568,9 @@
// If the database was deleted, jump to the error callback
if (m_database->deleted()) {
m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unable to open a transaction, because the user deleted the database");
- return nextStateForTransactionError();
+
+ handleTransactionError();
+ return SQLTransactionState::Idle;
}
// Set the maximum usage for this transaction if this transactions is not read-only
@@ -588,7 +593,9 @@
m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to begin transaction",
m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg());
m_sqliteTransaction = nullptr;
- return nextStateForTransactionError();
+
+ handleTransactionError();
+ return SQLTransactionState::Idle;
}
// Note: We intentionally retrieve the actual version even with an empty expected version.
@@ -601,8 +608,11 @@
m_database->disableAuthorizer();
m_sqliteTransaction = nullptr;
m_database->enableAuthorizer();
- return nextStateForTransactionError();
+
+ handleTransactionError();
+ return SQLTransactionState::Idle;
}
+
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
@@ -613,12 +623,16 @@
m_transactionError = m_wrapper->sqlError();
if (!m_transactionError)
m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction preflight");
- return nextStateForTransactionError();
+
+ handleTransactionError();
+ return SQLTransactionState::Idle;
}
// Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction object
- if (m_hasCallback)
- return SQLTransactionState::DeliverTransactionCallback;
+ if (m_hasCallback) {
+ m_frontend->requestTransitToState(SQLTransactionState::DeliverTransactionCallback);
+ return SQLTransactionState::Idle;
+ }
// If we have no callback to make, skip pass to the state after:
return SQLTransactionState::RunStatements;
@@ -627,7 +641,6 @@
SQLTransactionState SQLTransactionBackend::runStatements()
{
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
@@ -646,16 +659,22 @@
// 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();
+ handleCurrentStatementError();
+ break;
}
// Otherwise, advance to the next statement
getNextStatement();
}
- nextState = runCurrentStatementAndGetNextState();
- } while (nextState == SQLTransactionState::RunStatements);
+ } while (runCurrentStatement());
- return nextState;
+ // If runCurrentStatement() returned false, that means either there was no current statement to run,
+ // or the current statement requires a callback to complete. In the later case, it also scheduled
+ // the callback or performed any other additional work so we can return.
+ if (!m_currentStatementBackend)
+ postflightAndCommit();
+
+ return SQLTransactionState::Idle;
}
void SQLTransactionBackend::getNextStatement()
@@ -667,11 +686,11 @@
m_currentStatementBackend = m_statementQueue.takeFirst();
}
-SQLTransactionState SQLTransactionBackend::runCurrentStatementAndGetNextState()
+bool SQLTransactionBackend::runCurrentStatement()
{
if (!m_currentStatementBackend) {
// No more statements to run. So move on to the next state.
- return SQLTransactionState::PostflightAndCommit;
+ return false;
}
m_database->resetAuthorizer();
@@ -686,36 +705,55 @@
}
if (m_currentStatementBackend->hasStatementCallback()) {
- return SQLTransactionState::DeliverStatementCallback;
+ m_frontend->requestTransitToState(SQLTransactionState::DeliverStatementCallback);
+ return false;
}
// 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;
+ return true;
}
if (m_currentStatementBackend->lastExecutionFailedDueToQuota()) {
- return SQLTransactionState::DeliverQuotaIncreaseCallback;
+ m_frontend->requestTransitToState(SQLTransactionState::DeliverQuotaIncreaseCallback);
+ return false;
}
- return nextStateForCurrentStatementError();
+ handleCurrentStatementError();
+ return false;
}
-SQLTransactionState SQLTransactionBackend::nextStateForCurrentStatementError()
+void SQLTransactionBackend::handleCurrentStatementError()
{
// 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;
+ if (m_currentStatementBackend->hasStatementErrorCallback() && !m_sqliteTransaction->wasRolledBackBySqlite()) {
+ m_frontend->requestTransitToState(SQLTransactionState::DeliverStatementCallback);
+ return;
+ }
m_transactionError = m_currentStatementBackend->sqlError();
if (!m_transactionError)
m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "the statement failed to execute");
- return nextStateForTransactionError();
+
+ handleTransactionError();
}
-SQLTransactionState SQLTransactionBackend::postflightAndCommit()
+void SQLTransactionBackend::handleTransactionError()
{
+ ASSERT(m_transactionError);
+ if (m_hasErrorCallback) {
+ m_frontend->requestTransitToState(SQLTransactionState::DeliverTransactionErrorCallback);
+ return;
+ }
+
+ // No error callback, so fast-forward to the next state and rollback the
+ // transaction.
+ cleanupAfterTransactionErrorCallback();
+}
+
+void SQLTransactionBackend::postflightAndCommit()
+{
ASSERT(m_lockAcquired);
// Spec 4.3.2.7: Perform postflight steps, jumping to the error callback if they fail.
@@ -723,7 +761,9 @@
m_transactionError = m_wrapper->sqlError();
if (!m_transactionError)
m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction postflight");
- return nextStateForTransactionError();
+
+ handleTransactionError();
+ return;
}
// Spec 4.3.2.7: Commit the transaction, jumping to the error callback if that fails.
@@ -741,7 +781,9 @@
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();
+
+ handleTransactionError();
+ return;
}
// Vacuum the database if anything was deleted.
@@ -753,7 +795,7 @@
m_database->transactionClient()->didCommitWriteTransaction(database());
// Spec 4.3.2.8: Deliver success callback, if there is one.
- return SQLTransactionState::DeliverSuccessCallback;
+ m_frontend->requestTransitToState(SQLTransactionState::DeliverSuccessCallback);
}
SQLTransactionState SQLTransactionBackend::cleanupAndTerminate()
@@ -770,17 +812,6 @@
return SQLTransactionState::End;
}
-SQLTransactionState SQLTransactionBackend::nextStateForTransactionError()
-{
- 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;
-}
-
SQLTransactionState SQLTransactionBackend::cleanupAfterTransactionErrorCallback()
{
ASSERT(m_lockAcquired);
@@ -823,13 +854,6 @@
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);