Make SQLTransactionBackend a member of SQLTransaction
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Aug 2016 18:41:33 +0000 (18:41 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Aug 2016 18:41:33 +0000 (18:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160741

Reviewed by Tim Horton.

This is another step towards merging SQLTransaction and SQLTransactionBackend.

* Modules/webdatabase/Database.cpp:
(WebCore::Database::performClose):
(WebCore::Database::scheduleTransaction):
(WebCore::Database::scheduleTransactionStep):
(WebCore::Database::runTransaction):
* Modules/webdatabase/Database.h:
* Modules/webdatabase/DatabaseTask.cpp:
(WebCore::DatabaseTransactionTask::DatabaseTransactionTask):
(WebCore::DatabaseTransactionTask::~DatabaseTransactionTask):
(WebCore::DatabaseTransactionTask::doPerformTask):
* Modules/webdatabase/DatabaseTask.h:
(WebCore::DatabaseTransactionTask::transaction):
* Modules/webdatabase/DatabaseThread.cpp:
* Modules/webdatabase/SQLTransaction.cpp:
(WebCore::SQLTransaction::SQLTransaction):
(WebCore::SQLTransaction::deliverTransactionCallback):
(WebCore::SQLTransaction::deliverTransactionErrorCallback):
(WebCore::SQLTransaction::deliverStatementCallback):
(WebCore::SQLTransaction::deliverQuotaIncreaseCallback):
(WebCore::SQLTransaction::deliverSuccessCallback):
(WebCore::SQLTransaction::executeSQL):
(WebCore::SQLTransaction::computeNextStateAndCleanupIfNeeded):
(WebCore::SQLTransaction::setBackend): Deleted.
* Modules/webdatabase/SQLTransaction.h:
(WebCore::SQLTransaction::backend):
* Modules/webdatabase/SQLTransactionBackend.cpp:
(WebCore::SQLTransactionBackend::SQLTransactionBackend):
(WebCore::SQLTransactionBackend::doCleanup):
(WebCore::SQLTransactionBackend::computeNextStateAndCleanupIfNeeded):
(WebCore::SQLTransactionBackend::acquireLock):
(WebCore::SQLTransactionBackend::lockAcquired):
(WebCore::SQLTransactionBackend::openTransactionAndPreflight):
(WebCore::SQLTransactionBackend::runCurrentStatement):
(WebCore::SQLTransactionBackend::handleCurrentStatementError):
(WebCore::SQLTransactionBackend::handleTransactionError):
(WebCore::SQLTransactionBackend::postflightAndCommit):
(WebCore::SQLTransactionBackend::requestTransitToState):
(WebCore::SQLTransactionBackend::create): Deleted.
* Modules/webdatabase/SQLTransactionBackend.h:
* Modules/webdatabase/SQLTransactionCoordinator.cpp:
(WebCore::getDatabaseIdentifier):
(WebCore::SQLTransactionCoordinator::processPendingTransactions):
(WebCore::SQLTransactionCoordinator::acquireLock):
(WebCore::SQLTransactionCoordinator::releaseLock):
(WebCore::SQLTransactionCoordinator::shutdown):
* Modules/webdatabase/SQLTransactionCoordinator.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@204338 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/webdatabase/Database.cpp
Source/WebCore/Modules/webdatabase/Database.h
Source/WebCore/Modules/webdatabase/DatabaseTask.cpp
Source/WebCore/Modules/webdatabase/DatabaseTask.h
Source/WebCore/Modules/webdatabase/DatabaseThread.cpp
Source/WebCore/Modules/webdatabase/SQLTransaction.cpp
Source/WebCore/Modules/webdatabase/SQLTransaction.h
Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp
Source/WebCore/Modules/webdatabase/SQLTransactionBackend.h
Source/WebCore/Modules/webdatabase/SQLTransactionCoordinator.cpp
Source/WebCore/Modules/webdatabase/SQLTransactionCoordinator.h

index 4f3463d..57b80b9 100644 (file)
@@ -1,3 +1,59 @@
+2016-08-10  Anders Carlsson  <andersca@apple.com>
+
+        Make SQLTransactionBackend a member of SQLTransaction
+        https://bugs.webkit.org/show_bug.cgi?id=160741
+
+        Reviewed by Tim Horton.
+
+        This is another step towards merging SQLTransaction and SQLTransactionBackend.
+
+        * Modules/webdatabase/Database.cpp:
+        (WebCore::Database::performClose):
+        (WebCore::Database::scheduleTransaction):
+        (WebCore::Database::scheduleTransactionStep):
+        (WebCore::Database::runTransaction):
+        * Modules/webdatabase/Database.h:
+        * Modules/webdatabase/DatabaseTask.cpp:
+        (WebCore::DatabaseTransactionTask::DatabaseTransactionTask):
+        (WebCore::DatabaseTransactionTask::~DatabaseTransactionTask):
+        (WebCore::DatabaseTransactionTask::doPerformTask):
+        * Modules/webdatabase/DatabaseTask.h:
+        (WebCore::DatabaseTransactionTask::transaction):
+        * Modules/webdatabase/DatabaseThread.cpp:
+        * Modules/webdatabase/SQLTransaction.cpp:
+        (WebCore::SQLTransaction::SQLTransaction):
+        (WebCore::SQLTransaction::deliverTransactionCallback):
+        (WebCore::SQLTransaction::deliverTransactionErrorCallback):
+        (WebCore::SQLTransaction::deliverStatementCallback):
+        (WebCore::SQLTransaction::deliverQuotaIncreaseCallback):
+        (WebCore::SQLTransaction::deliverSuccessCallback):
+        (WebCore::SQLTransaction::executeSQL):
+        (WebCore::SQLTransaction::computeNextStateAndCleanupIfNeeded):
+        (WebCore::SQLTransaction::setBackend): Deleted.
+        * Modules/webdatabase/SQLTransaction.h:
+        (WebCore::SQLTransaction::backend):
+        * Modules/webdatabase/SQLTransactionBackend.cpp:
+        (WebCore::SQLTransactionBackend::SQLTransactionBackend):
+        (WebCore::SQLTransactionBackend::doCleanup):
+        (WebCore::SQLTransactionBackend::computeNextStateAndCleanupIfNeeded):
+        (WebCore::SQLTransactionBackend::acquireLock):
+        (WebCore::SQLTransactionBackend::lockAcquired):
+        (WebCore::SQLTransactionBackend::openTransactionAndPreflight):
+        (WebCore::SQLTransactionBackend::runCurrentStatement):
+        (WebCore::SQLTransactionBackend::handleCurrentStatementError):
+        (WebCore::SQLTransactionBackend::handleTransactionError):
+        (WebCore::SQLTransactionBackend::postflightAndCommit):
+        (WebCore::SQLTransactionBackend::requestTransitToState):
+        (WebCore::SQLTransactionBackend::create): Deleted.
+        * Modules/webdatabase/SQLTransactionBackend.h:
+        * Modules/webdatabase/SQLTransactionCoordinator.cpp:
+        (WebCore::getDatabaseIdentifier):
+        (WebCore::SQLTransactionCoordinator::processPendingTransactions):
+        (WebCore::SQLTransactionCoordinator::acquireLock):
+        (WebCore::SQLTransactionCoordinator::releaseLock):
+        (WebCore::SQLTransactionCoordinator::shutdown):
+        * Modules/webdatabase/SQLTransactionCoordinator.h:
+
 2016-08-08  Simon Fraser  <simon.fraser@apple.com>
 
         child-transform-with-anchor-point-expected.html renders incorrectly
index ee9c2da..b77c9ba 100644 (file)
@@ -314,7 +314,7 @@ void Database::performClose()
         // transaction is interrupted?" at the top of SQLTransactionBackend.cpp.
         while (!m_transactionQueue.isEmpty()) {
             auto transaction = m_transactionQueue.takeFirst();
-            transaction->notifyDatabaseThreadIsShuttingDown();
+            transaction->backend().notifyDatabaseThreadIsShuttingDown();
         }
 
         m_isTransactionQueueEnabled = false;
@@ -561,7 +561,7 @@ bool Database::getActualVersionForTransaction(String &actualVersion)
 void Database::scheduleTransaction()
 {
     ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller.
-    RefPtr<SQLTransactionBackend> transaction;
+    RefPtr<SQLTransaction> transaction;
 
     if (m_isTransactionQueueEnabled && !m_transactionQueue.isEmpty())
         transaction = m_transactionQueue.takeFirst();
@@ -575,7 +575,7 @@ void Database::scheduleTransaction()
         m_transactionInProgress = false;
 }
 
-void Database::scheduleTransactionStep(SQLTransactionBackend& transaction)
+void Database::scheduleTransactionStep(SQLTransaction& transaction)
 {
     if (!databaseContext()->databaseThread())
         return;
@@ -736,7 +736,7 @@ void Database::runTransaction(RefPtr<SQLTransactionCallback>&& callback, RefPtr<
     }
 
     auto transaction = SQLTransaction::create(*this, WTFMove(callback), WTFMove(successCallback), errorCallback.copyRef(), WTFMove(wrapper), readOnly);
-    m_transactionQueue.append(&transaction->backend());
+    m_transactionQueue.append(transaction.ptr());
     if (!m_transactionInProgress)
         scheduleTransaction();
 }
index 590c6b3..f146486 100644 (file)
@@ -66,7 +66,7 @@ public:
 
     unsigned long long maximumSize() const;
 
-    void scheduleTransactionStep(SQLTransactionBackend&);
+    void scheduleTransactionStep(SQLTransaction&);
     void inProgressTransactionCompleted();
 
     bool hasPendingTransaction();
@@ -166,7 +166,7 @@ private:
 
     RefPtr<DatabaseAuthorizer> m_databaseAuthorizer;
 
-    Deque<RefPtr<SQLTransactionBackend>> m_transactionQueue;
+    Deque<RefPtr<SQLTransaction>> m_transactionQueue;
     Lock m_transactionInProgressMutex;
     bool m_transactionInProgress;
     bool m_isTransactionQueueEnabled;
index e5c42da..741474d 100644 (file)
@@ -145,8 +145,8 @@ const char* DatabaseCloseTask::debugTaskName() const
 // *** DatabaseTransactionTask ***
 // Starts a transaction that will report its results via a callback.
 
-DatabaseTransactionTask::DatabaseTransactionTask(RefPtr<SQLTransactionBackend>&& transaction)
-    : DatabaseTask(*transaction->database(), 0)
+DatabaseTransactionTask::DatabaseTransactionTask(RefPtr<SQLTransaction>&& transaction)
+    : DatabaseTask(transaction->database(), 0)
     , m_transaction(WTFMove(transaction))
     , m_didPerformTask(false)
 {
@@ -163,12 +163,12 @@ DatabaseTransactionTask::~DatabaseTransactionTask()
     // transaction is interrupted?" at the top of SQLTransactionBackend.cpp.
 
     if (!m_didPerformTask)
-        m_transaction->notifyDatabaseThreadIsShuttingDown();
+        m_transaction->backend().notifyDatabaseThreadIsShuttingDown();
 }
 
 void DatabaseTransactionTask::doPerformTask()
 {
-    m_transaction->performNextStep();
+    m_transaction->backend().performNextStep();
     m_didPerformTask = true;
 }
 
index e5f475c..9b2f9c3 100644 (file)
@@ -122,10 +122,10 @@ private:
 
 class DatabaseTransactionTask : public DatabaseTask {
 public:
-    explicit DatabaseTransactionTask(RefPtr<SQLTransactionBackend>&&);
+    explicit DatabaseTransactionTask(RefPtr<SQLTransaction>&&);
     virtual ~DatabaseTransactionTask();
 
-    SQLTransactionBackend* transaction() const { return m_transaction.get(); }
+    SQLTransaction* transaction() const { return m_transaction.get(); }
 
 private:
     void doPerformTask() override;
@@ -133,7 +133,7 @@ private:
     const char* debugTaskName() const override;
 #endif
 
-    RefPtr<SQLTransactionBackend> m_transaction;
+    RefPtr<SQLTransaction> m_transaction;
     bool m_didPerformTask;
 };
 
index 3a1ae37..0bcf010 100644 (file)
@@ -32,6 +32,7 @@
 #include "Database.h"
 #include "DatabaseTask.h"
 #include "Logging.h"
+#include "SQLTransaction.h"
 #include "SQLTransactionClient.h"
 #include "SQLTransactionCoordinator.h"
 #include <wtf/AutodrainedPool.h>
index 4b136a5..464a5b0 100644 (file)
@@ -60,9 +60,8 @@ SQLTransaction::SQLTransaction(Ref<Database>&& database, RefPtr<SQLTransactionCa
     , m_errorCallbackWrapper(WTFMove(errorCallback), m_database->scriptExecutionContext())
     , m_executeSqlAllowed(false)
     , m_readOnly(readOnly)
+    , m_backend(m_database.ptr(), *this, WTFMove(wrapper), readOnly)
 {
-    // This will end up assigning to m_frontend.
-    SQLTransactionBackend::create(m_database.ptr(), this, WTFMove(wrapper), readOnly);
 }
 
 SQLTransaction::~SQLTransaction()
@@ -84,12 +83,6 @@ bool SQLTransaction::hasErrorCallback() const
     return m_errorCallbackWrapper.hasCallback();
 }
 
-void SQLTransaction::setBackend(SQLTransactionBackend* backend)
-{
-    ASSERT(!m_backend);
-    m_backend = backend;
-}
-
 SQLTransaction::StateFunction SQLTransaction::stateFunctionFor(SQLTransactionState state)
 {
     static const StateFunction stateFunctions[] = {
@@ -142,7 +135,7 @@ void SQLTransaction::deliverTransactionCallback()
         return deliverTransactionErrorCallback();
     }
 
-    m_backend->requestTransitToState(SQLTransactionState::RunStatements);
+    m_backend.requestTransitToState(SQLTransactionState::RunStatements);
 }
 
 void SQLTransaction::deliverTransactionErrorCallback()
@@ -156,7 +149,7 @@ void SQLTransaction::deliverTransactionErrorCallback()
         // Hence, it's thread safe to fetch the backend transactionError without
         // a lock.
         if (!m_transactionError)
-            m_transactionError = m_backend->transactionError();
+            m_transactionError = m_backend.transactionError();
 
         ASSERT(m_transactionError);
         errorCallback->handleEvent(m_transactionError.get());
@@ -167,7 +160,7 @@ void SQLTransaction::deliverTransactionErrorCallback()
     clearCallbackWrappers();
 
     // Spec 4.3.2.10: Rollback the transaction.
-    m_backend->requestTransitToState(SQLTransactionState::CleanupAfterTransactionErrorCallback);
+    m_backend.requestTransitToState(SQLTransactionState::CleanupAfterTransactionErrorCallback);
 }
 
 void SQLTransaction::deliverStatementCallback()
@@ -176,7 +169,7 @@ void SQLTransaction::deliverStatementCallback()
     // Otherwise, continue to loop through the statement queue
     m_executeSqlAllowed = true;
 
-    SQLStatement* currentStatement = m_backend->currentStatement();
+    SQLStatement* currentStatement = m_backend.currentStatement();
     ASSERT(currentStatement);
 
     bool result = currentStatement->performCallback(this);
@@ -191,21 +184,21 @@ void SQLTransaction::deliverStatementCallback()
 
         // No error callback, so fast-forward to:
         // Transaction Step 11 - Rollback the transaction.
-        m_backend->requestTransitToState(SQLTransactionState::CleanupAfterTransactionErrorCallback);
+        m_backend.requestTransitToState(SQLTransactionState::CleanupAfterTransactionErrorCallback);
         return;
     }
 
-    m_backend->requestTransitToState(SQLTransactionState::RunStatements);
+    m_backend.requestTransitToState(SQLTransactionState::RunStatements);
 }
 
 void SQLTransaction::deliverQuotaIncreaseCallback()
 {
-    ASSERT(m_backend->currentStatement());
+    ASSERT(m_backend.currentStatement());
 
     bool shouldRetryCurrentStatement = m_database->transactionClient()->didExceedQuota(&database());
-    m_backend->setShouldRetryCurrentStatement(shouldRetryCurrentStatement);
+    m_backend.setShouldRetryCurrentStatement(shouldRetryCurrentStatement);
 
-    m_backend->requestTransitToState(SQLTransactionState::RunStatements);
+    m_backend.requestTransitToState(SQLTransactionState::RunStatements);
 }
 
 void SQLTransaction::deliverSuccessCallback()
@@ -219,7 +212,7 @@ void SQLTransaction::deliverSuccessCallback()
 
     // Schedule a "post-success callback" step to return control to the database thread in case there
     // are further transactions queued up for this Database
-    m_backend->requestTransitToState(SQLTransactionState::CleanupAndTerminate);
+    m_backend.requestTransitToState(SQLTransactionState::CleanupAndTerminate);
 }
 
 // This state function is used as a stub function to plug unimplemented states
@@ -250,7 +243,7 @@ void SQLTransaction::executeSQL(const String& sqlStatement, const Vector<SQLValu
         permissions |= DatabaseAuthorizer::ReadOnlyMask;
 
     auto statement = std::make_unique<SQLStatement>(m_database, sqlStatement, arguments, WTFMove(callback), WTFMove(callbackError), permissions);
-    m_backend->executeSQL(WTFMove(statement));
+    m_backend.executeSQL(WTFMove(statement));
 }
 
 void SQLTransaction::computeNextStateAndCleanupIfNeeded()
@@ -271,7 +264,7 @@ void SQLTransaction::computeNextStateAndCleanupIfNeeded()
     }
 
     clearCallbackWrappers();
-    m_backend->requestTransitToState(SQLTransactionState::CleanupAndTerminate);
+    m_backend.requestTransitToState(SQLTransactionState::CleanupAndTerminate);
 }
 
 void SQLTransaction::clearCallbackWrappers()
index b25e8e4..15d13a5 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "EventTarget.h"
 #include "SQLCallbackWrapper.h"
+#include "SQLTransactionBackend.h"
 #include "SQLTransactionStateMachine.h"
 #include <wtf/Ref.h>
 #include <wtf/RefPtr.h>
@@ -66,14 +67,13 @@ public:
     void performPendingCallback();
 
     Database& database() { return m_database; }
-    SQLTransactionBackend& backend() { return *m_backend; }
+    SQLTransactionBackend& backend() { return m_backend; }
 
     // APIs called from the backend published via SQLTransaction:
     void requestTransitToState(SQLTransactionState);
     bool hasCallback() const;
     bool hasSuccessCallback() const;
     bool hasErrorCallback() const;
-    void setBackend(SQLTransactionBackend*);
 
 private:
     SQLTransaction(Ref<Database>&&, RefPtr<SQLTransactionCallback>&&, RefPtr<VoidCallback>&& successCallback, RefPtr<SQLTransactionErrorCallback>&&, RefPtr<SQLTransactionWrapper>&&, bool readOnly);
@@ -94,7 +94,6 @@ private:
     NO_RETURN_DUE_TO_ASSERT void unreachableState();
 
     Ref<Database> m_database;
-    RefPtr<SQLTransactionBackend> m_backend;
     SQLCallbackWrapper<SQLTransactionCallback> m_callbackWrapper;
     SQLCallbackWrapper<VoidCallback> m_successCallbackWrapper;
     SQLCallbackWrapper<SQLTransactionErrorCallback> m_errorCallbackWrapper;
@@ -103,6 +102,8 @@ private:
     RefPtr<SQLError> m_transactionError;
 
     bool m_readOnly;
+
+    SQLTransactionBackend m_backend;
 };
 
 } // namespace WebCore
index a84c83b..0ed6aa8 100644 (file)
 
 namespace WebCore {
 
-Ref<SQLTransactionBackend> SQLTransactionBackend::create(Database* db, RefPtr<SQLTransaction>&& frontend, RefPtr<SQLTransactionWrapper>&& wrapper, bool readOnly)
-{
-    return adoptRef(*new SQLTransactionBackend(db, WTFMove(frontend), WTFMove(wrapper), readOnly));
-}
-
-SQLTransactionBackend::SQLTransactionBackend(Database* db, RefPtr<SQLTransaction>&& frontend, RefPtr<SQLTransactionWrapper>&& wrapper, bool readOnly)
-    : m_frontend(WTFMove(frontend))
+SQLTransactionBackend::SQLTransactionBackend(Database* db, SQLTransaction& frontend, RefPtr<SQLTransactionWrapper>&& wrapper, bool readOnly)
+    : m_frontend(frontend)
     , m_database(db)
     , m_wrapper(WTFMove(wrapper))
-    , m_hasCallback(m_frontend->hasCallback())
-    , m_hasSuccessCallback(m_frontend->hasSuccessCallback())
-    , m_hasErrorCallback(m_frontend->hasErrorCallback())
+    , m_hasCallback(m_frontend.hasCallback())
+    , m_hasSuccessCallback(m_frontend.hasSuccessCallback())
+    , m_hasErrorCallback(m_frontend.hasErrorCallback())
     , m_shouldRetryCurrentStatement(false)
     , m_modifiedDatabase(false)
     , m_lockAcquired(false)
@@ -362,7 +357,6 @@ SQLTransactionBackend::SQLTransactionBackend(Database* db, RefPtr<SQLTransaction
     , m_hasVersionMismatch(false)
 {
     ASSERT(m_database);
-    m_frontend->setBackend(this);
     m_requestedState = SQLTransactionState::AcquireLock;
 }
 
@@ -373,10 +367,6 @@ SQLTransactionBackend::~SQLTransactionBackend()
 
 void SQLTransactionBackend::doCleanup()
 {
-    if (!m_frontend)
-        return;
-    m_frontend = nullptr; // Break the reference cycle. See comment about the life-cycle above.
-
     ASSERT(currentThread() == database()->databaseContext()->databaseThread()->getThreadID());
 
     releaseOriginLockIfNeeded();
@@ -395,7 +385,7 @@ void SQLTransactionBackend::doCleanup()
 
     // Release the lock on this database
     if (m_lockAcquired)
-        m_database->transactionCoordinator()->releaseLock(this);
+        m_database->transactionCoordinator()->releaseLock(m_frontend);
 
     // Do some aggresive clean up here except for m_database.
     //
@@ -503,7 +493,7 @@ void SQLTransactionBackend::computeNextStateAndCleanupIfNeeded()
     // 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();
@@ -537,7 +527,7 @@ void SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown()
 
 void SQLTransactionBackend::acquireLock()
 {
-    m_database->transactionCoordinator()->acquireLock(this);
+    m_database->transactionCoordinator()->acquireLock(m_frontend);
 }
 
 void SQLTransactionBackend::lockAcquired()
@@ -546,7 +536,7 @@ void SQLTransactionBackend::lockAcquired()
 
     m_requestedState = SQLTransactionState::OpenTransactionAndPreflight;
     ASSERT(m_requestedState != SQLTransactionState::End);
-    m_database->scheduleTransactionStep(*this);
+    m_database->scheduleTransactionStep(m_frontend);
 }
 
 void SQLTransactionBackend::openTransactionAndPreflight()
@@ -621,7 +611,7 @@ void SQLTransactionBackend::openTransactionAndPreflight()
 
     // Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction object
     if (m_hasCallback) {
-        m_frontend->requestTransitToState(SQLTransactionState::DeliverTransactionCallback);
+        m_frontend.requestTransitToState(SQLTransactionState::DeliverTransactionCallback);
         return;
     }
 
@@ -694,7 +684,7 @@ bool SQLTransactionBackend::runCurrentStatement()
         }
 
         if (m_currentStatementBackend->hasStatementCallback()) {
-            m_frontend->requestTransitToState(SQLTransactionState::DeliverStatementCallback);
+            m_frontend.requestTransitToState(SQLTransactionState::DeliverStatementCallback);
             return false;
         }
 
@@ -704,7 +694,7 @@ bool SQLTransactionBackend::runCurrentStatement()
     }
 
     if (m_currentStatementBackend->lastExecutionFailedDueToQuota()) {
-        m_frontend->requestTransitToState(SQLTransactionState::DeliverQuotaIncreaseCallback);
+        m_frontend.requestTransitToState(SQLTransactionState::DeliverQuotaIncreaseCallback);
         return false;
     }
 
@@ -717,7 +707,7 @@ 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()) {
-        m_frontend->requestTransitToState(SQLTransactionState::DeliverStatementCallback);
+        m_frontend.requestTransitToState(SQLTransactionState::DeliverStatementCallback);
         return;
     }
 
@@ -732,7 +722,7 @@ void SQLTransactionBackend::handleTransactionError()
 {
     ASSERT(m_transactionError);
     if (m_hasErrorCallback) {
-        m_frontend->requestTransitToState(SQLTransactionState::DeliverTransactionErrorCallback);
+        m_frontend.requestTransitToState(SQLTransactionState::DeliverTransactionErrorCallback);
         return;
     }
 
@@ -784,7 +774,7 @@ void SQLTransactionBackend::postflightAndCommit()
         m_database->transactionClient()->didCommitWriteTransaction(database());
 
     // Spec 4.3.2.8: Deliver success callback, if there is one.
-    m_frontend->requestTransitToState(SQLTransactionState::DeliverSuccessCallback);
+    m_frontend.requestTransitToState(SQLTransactionState::DeliverSuccessCallback);
 }
 
 void SQLTransactionBackend::cleanupAndTerminate()
@@ -830,7 +820,7 @@ 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_database->scheduleTransactionStep(m_frontend);
 }
 
 // This state function is used as a stub function to plug unimplemented states
index 9cdc208..71c1723 100644 (file)
@@ -47,11 +47,10 @@ class SQLTransaction;
 class SQLTransactionWrapper;
 class SQLValue;
 
-class SQLTransactionBackend : public ThreadSafeRefCounted<SQLTransactionBackend>, public SQLTransactionStateMachine<SQLTransactionBackend> {
+class SQLTransactionBackend : public SQLTransactionStateMachine<SQLTransactionBackend> {
 public:
-    static Ref<SQLTransactionBackend> create(Database*, RefPtr<SQLTransaction>&&, RefPtr<SQLTransactionWrapper>&&, bool readOnly);
-
-    virtual ~SQLTransactionBackend();
+    SQLTransactionBackend(Database*, SQLTransaction&, RefPtr<SQLTransactionWrapper>&&, bool readOnly);
+    ~SQLTransactionBackend();
 
     void lockAcquired();
     void performNextStep();
@@ -68,7 +67,6 @@ public:
     void executeSQL(std::unique_ptr<SQLStatement>);
     
 private:
-    SQLTransactionBackend(Database*, RefPtr<SQLTransaction>&&, RefPtr<SQLTransactionWrapper>&&, bool readOnly);
 
     void doCleanup();
 
@@ -96,7 +94,7 @@ private:
     void acquireOriginLock();
     void releaseOriginLockIfNeeded();
 
-    RefPtr<SQLTransaction> m_frontend; // Has a reference cycle, and will break in doCleanup().
+    SQLTransaction& m_frontend;
     std::unique_ptr<SQLStatement> m_currentStatementBackend;
 
     RefPtr<Database> m_database;
index 843328c..5b27d3d 100644 (file)
@@ -33,7 +33,7 @@
 #include "SQLTransactionCoordinator.h"
 
 #include "Database.h"
-#include "SQLTransactionBackend.h"
+#include "SQLTransaction.h"
 #include "SecurityOrigin.h"
 #include <wtf/Deque.h>
 #include <wtf/HashMap.h>
 
 namespace WebCore {
 
-static String getDatabaseIdentifier(SQLTransactionBackend* transaction)
+static String getDatabaseIdentifier(SQLTransaction& transaction)
 {
-    Database* database = transaction->database();
-    ASSERT(database);
-    return database->securityOrigin()->databaseIdentifier();
+    return transaction.database().securityOrigin()->databaseIdentifier();
 }
 
 SQLTransactionCoordinator::SQLTransactionCoordinator()
@@ -59,21 +57,21 @@ void SQLTransactionCoordinator::processPendingTransactions(CoordinationInfo& inf
     if (info.activeWriteTransaction || info.pendingTransactions.isEmpty())
         return;
 
-    RefPtr<SQLTransactionBackend> firstPendingTransaction = info.pendingTransactions.first();
-    if (firstPendingTransaction->isReadOnly()) {
+    RefPtr<SQLTransaction> firstPendingTransaction = info.pendingTransactions.first();
+    if (firstPendingTransaction->backend().isReadOnly()) {
         do {
             firstPendingTransaction = info.pendingTransactions.takeFirst();
             info.activeReadTransactions.add(firstPendingTransaction);
-            firstPendingTransaction->lockAcquired();
-        } while (!info.pendingTransactions.isEmpty() && info.pendingTransactions.first()->isReadOnly());
+            firstPendingTransaction->backend().lockAcquired();
+        } while (!info.pendingTransactions.isEmpty() && info.pendingTransactions.first()->backend().isReadOnly());
     } else if (info.activeReadTransactions.isEmpty()) {
         info.pendingTransactions.removeFirst();
         info.activeWriteTransaction = firstPendingTransaction;
-        firstPendingTransaction->lockAcquired();
+        firstPendingTransaction->backend().lockAcquired();
     }
 }
 
-void SQLTransactionCoordinator::acquireLock(SQLTransactionBackend* transaction)
+void SQLTransactionCoordinator::acquireLock(SQLTransaction& transaction)
 {
     ASSERT(!m_isShuttingDown);
 
@@ -86,11 +84,11 @@ void SQLTransactionCoordinator::acquireLock(SQLTransactionBackend* transaction)
     }
 
     CoordinationInfo& info = coordinationInfoIterator->value;
-    info.pendingTransactions.append(transaction);
+    info.pendingTransactions.append(&transaction);
     processPendingTransactions(info);
 }
 
-void SQLTransactionCoordinator::releaseLock(SQLTransactionBackend* transaction)
+void SQLTransactionCoordinator::releaseLock(SQLTransaction& transaction)
 {
     if (m_isShuttingDown)
         return;
@@ -101,11 +99,11 @@ void SQLTransactionCoordinator::releaseLock(SQLTransactionBackend* transaction)
     ASSERT(coordinationInfoIterator != m_coordinationInfoMap.end());
     CoordinationInfo& info = coordinationInfoIterator->value;
 
-    if (transaction->isReadOnly()) {
-        ASSERT(info.activeReadTransactions.contains(transaction));
-        info.activeReadTransactions.remove(transaction);
+    if (transaction.backend().isReadOnly()) {
+        ASSERT(info.activeReadTransactions.contains(&transaction));
+        info.activeReadTransactions.remove(&transaction);
     } else {
-        ASSERT(info.activeWriteTransaction == transaction);
+        ASSERT(info.activeWriteTransaction == &transaction);
         info.activeWriteTransaction = nullptr;
     }
 
@@ -124,16 +122,16 @@ void SQLTransactionCoordinator::shutdown()
         // Transaction phase 4 cleanup. See comment on "What happens if a
         // transaction is interrupted?" at the top of SQLTransactionBackend.cpp.
         if (info.activeWriteTransaction)
-            info.activeWriteTransaction->notifyDatabaseThreadIsShuttingDown();
+            info.activeWriteTransaction->backend().notifyDatabaseThreadIsShuttingDown();
         for (auto& transaction : info.activeReadTransactions)
-            transaction->notifyDatabaseThreadIsShuttingDown();
+            transaction->backend().notifyDatabaseThreadIsShuttingDown();
 
         // Clean up transactions that have NOT reached "lockAcquired":
         // Transaction phase 3 cleanup. See comment on "What happens if a
         // transaction is interrupted?" at the top of SQLTransactionBackend.cpp.
         while (!info.pendingTransactions.isEmpty()) {
-            RefPtr<SQLTransactionBackend> transaction = info.pendingTransactions.first();
-            transaction->notifyDatabaseThreadIsShuttingDown();
+            RefPtr<SQLTransaction> transaction = info.pendingTransactions.first();
+            transaction->backend().notifyDatabaseThreadIsShuttingDown();
         }
     }
 
index 4a7ae26..cf44ece 100644 (file)
 
 namespace WebCore {
 
-class SQLTransactionBackend;
+class SQLTransaction;
 
 class SQLTransactionCoordinator {
     WTF_MAKE_NONCOPYABLE(SQLTransactionCoordinator); WTF_MAKE_FAST_ALLOCATED;
 public:
     SQLTransactionCoordinator();
-    void acquireLock(SQLTransactionBackend*);
-    void releaseLock(SQLTransactionBackend*);
+    void acquireLock(SQLTransaction&);
+    void releaseLock(SQLTransaction&);
     void shutdown();
 private:
-    typedef Deque<RefPtr<SQLTransactionBackend>> TransactionsQueue;
+    typedef Deque<RefPtr<SQLTransaction>> TransactionsQueue;
     struct CoordinationInfo {
         TransactionsQueue pendingTransactions;
-        HashSet<RefPtr<SQLTransactionBackend>> activeReadTransactions;
-        RefPtr<SQLTransactionBackend> activeWriteTransaction;
+        HashSet<RefPtr<SQLTransaction>> activeReadTransactions;
+        RefPtr<SQLTransaction> activeWriteTransaction;
     };
     // Maps database names to information about pending transactions
     typedef HashMap<String, CoordinationInfo> CoordinationInfoMap;