Skip to content
Permalink
Browse files
Revert back to the old style member function state machine for callbacks
https://bugs.webkit.org/show_bug.cgi?id=160756

Reviewed by Tim Horton.

This is another step towards merging SQLTransactionBackend and SQLTransaction,
and using a single state machine for both sides.

* Modules/webdatabase/SQLTransaction.cpp:
(WebCore::SQLTransaction::SQLTransaction):
(WebCore::SQLTransaction::performPendingCallback):
(WebCore::SQLTransaction::checkAndHandleClosedDatabase):
(WebCore::SQLTransaction::scheduleCallback):
(WebCore::SQLTransaction::openTransactionAndPreflight):
(WebCore::SQLTransaction::runCurrentStatement):
(WebCore::SQLTransaction::handleCurrentStatementError):
(WebCore::SQLTransaction::handleTransactionError):
(WebCore::SQLTransaction::postflightAndCommit):
(WebCore::SQLTransaction::debugStepName):
* Modules/webdatabase/SQLTransaction.h:

Canonical link: https://commits.webkit.org/178870@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@204359 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Anders Carlsson committed Aug 10, 2016
1 parent 3e72663 commit 6b2de13d296ac2ba4c019b05945b62cea4c12fb7
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 8 deletions.
@@ -1,3 +1,26 @@
2016-08-10 Anders Carlsson <andersca@apple.com>

Revert back to the old style member function state machine for callbacks
https://bugs.webkit.org/show_bug.cgi?id=160756

Reviewed by Tim Horton.

This is another step towards merging SQLTransactionBackend and SQLTransaction,
and using a single state machine for both sides.

* Modules/webdatabase/SQLTransaction.cpp:
(WebCore::SQLTransaction::SQLTransaction):
(WebCore::SQLTransaction::performPendingCallback):
(WebCore::SQLTransaction::checkAndHandleClosedDatabase):
(WebCore::SQLTransaction::scheduleCallback):
(WebCore::SQLTransaction::openTransactionAndPreflight):
(WebCore::SQLTransaction::runCurrentStatement):
(WebCore::SQLTransaction::handleCurrentStatementError):
(WebCore::SQLTransaction::handleTransactionError):
(WebCore::SQLTransaction::postflightAndCommit):
(WebCore::SQLTransaction::debugStepName):
* Modules/webdatabase/SQLTransaction.h:

2016-08-09 Skachkov Oleksandr <gskachkov@gmail.com>

[ES2016] Implement Object.values
@@ -32,6 +32,7 @@
#include "Database.h"
#include "DatabaseAuthorizer.h"
#include "DatabaseContext.h"
#include "DatabaseThread.h"
#include "DatabaseTracker.h"
#include "ExceptionCode.h"
#include "Logging.h"
@@ -63,6 +64,7 @@ SQLTransaction::SQLTransaction(Ref<Database>&& database, RefPtr<SQLTransactionCa
, m_successCallbackWrapper(WTFMove(successCallback), m_database->scriptExecutionContext())
, m_errorCallbackWrapper(WTFMove(errorCallback), m_database->scriptExecutionContext())
, m_wrapper(WTFMove(wrapper))
, m_nextStep(&SQLTransaction::acquireLock)
, m_executeSqlAllowed(false)
, m_shouldRetryCurrentStatement(false)
, m_modifiedDatabase(false)
@@ -114,8 +116,18 @@ void SQLTransaction::performNextStep()

void SQLTransaction::performPendingCallback()
{
computeNextStateAndCleanupIfNeeded();
runStateMachine();
LOG(StorageAPI, "Callback %s\n", debugStepName(m_nextStep));

ASSERT(m_nextStep == &SQLTransaction::deliverTransactionCallback
|| m_nextStep == &SQLTransaction::deliverTransactionErrorCallback
|| m_nextStep == &SQLTransaction::deliverStatementCallback
|| m_nextStep == &SQLTransaction::deliverQuotaIncreaseCallback
|| m_nextStep == &SQLTransaction::deliverSuccessCallback);

checkAndHandleClosedDatabase();

if (m_nextStep)
(this->*m_nextStep)();
}

void SQLTransaction::notifyDatabaseThreadIsShuttingDown()
@@ -163,6 +175,45 @@ void SQLTransaction::requestTransitToState(SQLTransactionState nextState)
m_database->scheduleTransactionCallback(this);
}

void SQLTransaction::checkAndHandleClosedDatabase()
{
if (m_database->opened())
return;

// If the database was stopped, don't do anything and cancel queued work
LOG(StorageAPI, "Database was stopped or interrupted - cancelling work for this transaction");

LockHolder locker(m_statementMutex);
m_statementQueue.clear();
m_nextStep = nullptr;

// Release the unneeded callbacks, to break reference cycles.
m_callbackWrapper.clear();
m_successCallbackWrapper.clear();
m_errorCallbackWrapper.clear();

// The next steps should be executed only if we're on the DB thread.
if (currentThread() != m_database->databaseContext()->databaseThread()->getThreadID())
return;

// The current SQLite transaction should be stopped, as well
if (m_sqliteTransaction) {
m_sqliteTransaction->stop();
m_sqliteTransaction = nullptr;
}

if (m_lockAcquired)
m_database->transactionCoordinator()->releaseLock(*this);
}

void SQLTransaction::scheduleCallback(void (SQLTransaction::*step)())
{
m_nextStep = step;

LOG(StorageAPI, "Scheduling %s for transaction %p\n", debugStepName(step), this);
m_database->scheduleTransactionCallback(this);
}

void SQLTransaction::acquireLock()
{
m_database->transactionCoordinator()->acquireLock(*this);
@@ -238,7 +289,7 @@ void SQLTransaction::openTransactionAndPreflight()

// Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction object
if (m_callbackWrapper.hasCallback()) {
requestTransitToState(SQLTransactionState::DeliverTransactionCallback);
scheduleCallback(&SQLTransaction::deliverTransactionCallback);
return;
}

@@ -469,7 +520,7 @@ bool SQLTransaction::runCurrentStatement()
}

if (m_currentStatement->hasStatementCallback()) {
requestTransitToState(SQLTransactionState::DeliverStatementCallback);
scheduleCallback(&SQLTransaction::deliverStatementCallback);
return false;
}

@@ -479,7 +530,7 @@ bool SQLTransaction::runCurrentStatement()
}

if (m_currentStatement->lastExecutionFailedDueToQuota()) {
requestTransitToState(SQLTransactionState::DeliverQuotaIncreaseCallback);
scheduleCallback(&SQLTransaction::deliverQuotaIncreaseCallback);
return false;
}

@@ -492,7 +543,7 @@ void SQLTransaction::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_currentStatement->hasStatementErrorCallback() && !m_sqliteTransaction->wasRolledBackBySqlite()) {
requestTransitToState(SQLTransactionState::DeliverStatementCallback);
scheduleCallback(&SQLTransaction::deliverStatementCallback);
return;
}

@@ -507,7 +558,7 @@ void SQLTransaction::handleTransactionError()
{
ASSERT(m_transactionError);
if (m_errorCallbackWrapper.hasCallback()) {
requestTransitToState(SQLTransactionState::DeliverTransactionErrorCallback);
scheduleCallback(&SQLTransaction::deliverTransactionErrorCallback);
return;
}

@@ -558,7 +609,7 @@ void SQLTransaction::postflightAndCommit()
m_database->transactionClient()->didCommitWriteTransaction(m_database.ptr());

// Spec 4.3.2.8: Deliver success callback, if there is one.
requestTransitToState(SQLTransactionState::DeliverSuccessCallback);
scheduleCallback(&SQLTransaction::deliverSuccessCallback);
}

void SQLTransaction::acquireOriginLock()
@@ -576,4 +627,33 @@ void SQLTransaction::releaseOriginLockIfNeeded()
}
}

#if !LOG_DISABLED
const char* SQLTransaction::debugStepName(void (SQLTransaction::*step)())
{
if (step == &SQLTransaction::acquireLock)
return "acquireLock";
if (step == &SQLTransaction::openTransactionAndPreflight)
return "openTransactionAndPreflight";
if (step == &SQLTransaction::runStatements)
return "runStatements";
if (step == &SQLTransaction::postflightAndCommit)
return "postflightAndCommit";
if (step == &SQLTransaction::cleanupAfterTransactionErrorCallback)
return "cleanupAfterTransactionErrorCallback";
if (step == &SQLTransaction::deliverTransactionCallback)
return "deliverTransactionCallback";
if (step == &SQLTransaction::deliverTransactionErrorCallback)
return "deliverTransactionErrorCallback";
if (step == &SQLTransaction::deliverStatementCallback)
return "deliverStatementCallback";
if (step == &SQLTransaction::deliverQuotaIncreaseCallback)
return "deliverQuotaIncreaseCallback";
if (step == &SQLTransaction::deliverSuccessCallback)
return "deliverSuccessCallback";

ASSERT_NOT_REACHED();
return "UNKNOWN";
}
#endif

} // namespace WebCore
@@ -82,8 +82,12 @@ class SQLTransaction : public ThreadSafeRefCounted<SQLTransaction>, public SQLTr

void enqueueStatement(std::unique_ptr<SQLStatement>);

void checkAndHandleClosedDatabase();

void clearCallbackWrappers();

void scheduleCallback(void (SQLTransaction::*)());

// State Machine functions:
StateFunction stateFunctionFor(SQLTransactionState) override;
void computeNextStateAndCleanupIfNeeded();
@@ -111,13 +115,19 @@ class SQLTransaction : public ThreadSafeRefCounted<SQLTransaction>, public SQLTr
void acquireOriginLock();
void releaseOriginLockIfNeeded();

#if !LOG_DISABLED
static const char* debugStepName(void (SQLTransaction::*)());
#endif

Ref<Database> m_database;
SQLCallbackWrapper<SQLTransactionCallback> m_callbackWrapper;
SQLCallbackWrapper<VoidCallback> m_successCallbackWrapper;
SQLCallbackWrapper<SQLTransactionErrorCallback> m_errorCallbackWrapper;

RefPtr<SQLTransactionWrapper> m_wrapper;

void (SQLTransaction::*m_nextStep)();

bool m_executeSqlAllowed;
RefPtr<SQLError> m_transactionError;

0 comments on commit 6b2de13

Please sign in to comment.