Changeset 209069 in webkit


Ignore:
Timestamp:
Nov 29, 2016 8:05:17 AM (7 years ago)
Author:
beidson@apple.com
Message:

IndexedDB 2.0: Queue up completed requests in the client, handle them one by one.
https://bugs.webkit.org/show_bug.cgi?id=165000

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (Covered extensively by every existing test).

Currently when a TransactionOperation completes on the server, it immediately completes
itself on the client side, including scheduling an event dispatch if necessary.

This patch changes it so that "server completed operations" instead queue up in the
IDBTransaction and are "client-side completed" asynchronously, 1-by-1.

Currently this is a "no behavior change" because only one operation is ever sent to
the server at a time.

But that will change with https://webkit.org/b/164932
And this patch is a pre-requisite for that.

  • Modules/indexeddb/IDBRequest.cpp:

(WebCore::IDBRequest::dispatchEvent):
(WebCore::IDBRequest::didOpenOrIterateCursor):
(WebCore::IDBRequest::completeRequestAndDispatchEvent):
(WebCore::IDBRequest::requestCompleted): Deleted.

  • Modules/indexeddb/IDBRequest.h:
  • Modules/indexeddb/IDBTransaction.cpp:

(WebCore::IDBTransaction::IDBTransaction):
(WebCore::IDBTransaction::internalAbort):
(WebCore::IDBTransaction::abortOnServerAndCancelRequests):
(WebCore::IDBTransaction::scheduleOperation):
(WebCore::IDBTransaction::schedulePendingOperationTimer):
(WebCore::IDBTransaction::pendingOperationTimerFired):
(WebCore::IDBTransaction::operationCompletedOnServer):
(WebCore::IDBTransaction::scheduleCompletedOperationTimer):
(WebCore::IDBTransaction::completedOperationTimerFired):
(WebCore::IDBTransaction::completeNoncursorRequest):
(WebCore::IDBTransaction::completeCursorRequest):
(WebCore::IDBTransaction::finishedDispatchEventForRequest):
(WebCore::IDBTransaction::didStart):
(WebCore::IDBTransaction::didOpenCursorOnServer):
(WebCore::IDBTransaction::didIterateCursorOnServer):
(WebCore::IDBTransaction::didGetAllRecordsOnServer):
(WebCore::IDBTransaction::didGetRecordOnServer):
(WebCore::IDBTransaction::didGetCountOnServer):
(WebCore::IDBTransaction::didDeleteRecordOnServer):
(WebCore::IDBTransaction::didClearObjectStoreOnServer):
(WebCore::IDBTransaction::putOrAddOnServer):
(WebCore::IDBTransaction::didPutOrAddOnServer):
(WebCore::IDBTransaction::operationCompletedOnClient):
(WebCore::IDBTransaction::deactivate):
(WebCore::IDBTransaction::connectionClosedFromServer):
(WebCore::IDBTransaction::scheduleOperationTimer): Deleted.
(WebCore::IDBTransaction::operationTimerFired): Deleted.
(WebCore::IDBTransaction::operationDidComplete): Deleted.

  • Modules/indexeddb/IDBTransaction.h:
  • Modules/indexeddb/client/IDBConnectionProxy.cpp:

(WebCore::IDBClient::IDBConnectionProxy::completeOperation):

  • Modules/indexeddb/client/TransactionOperation.cpp:

(WebCore::IDBClient::TransactionOperation::TransactionOperation):

  • Modules/indexeddb/client/TransactionOperation.h:

(WebCore::IDBClient::TransactionOperation::transitionToCompleteOnThisThread):
(WebCore::IDBClient::TransactionOperation::transitionToComplete):
(WebCore::IDBClient::TransactionOperation::doComplete):
(WebCore::IDBClient::TransactionOperation::idbRequest):
(WebCore::IDBClient::TransactionOperation::performCompleteOnOriginThread): Deleted.
(WebCore::IDBClient::TransactionOperation::completed): Deleted.

LayoutTests:

  • storage/indexeddb/modern/resources/transaction-scheduler-6.js: This test had a bug which was masked by previously synchronous behavior. Fix that bug!
Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r209068 r209069  
     12016-11-29  Brady Eidson  <beidson@apple.com>
     2
     3        IndexedDB 2.0: Queue up completed requests in the client, handle them one by one.
     4        https://bugs.webkit.org/show_bug.cgi?id=165000
     5
     6        Reviewed by Alex Christensen.
     7
     8        * storage/indexeddb/modern/resources/transaction-scheduler-6.js: This test had a bug which was masked by previously
     9          synchronous behavior. Fix that bug!
     10
    1112016-11-29  Zalan Bujtas  <zalan@apple.com>
    212
  • trunk/LayoutTests/storage/indexeddb/modern/resources/transaction-scheduler-6.js

    r195380 r209069  
    44indexedDBTest(prepareDatabase);
    55
     6function log(msg)
     7{
     8        debug(msg);
     9}
    610
    711function done()
     
    1418function prepareDatabase(event)
    1519{
    16     debug("Upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
     20    log("Upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
    1721
    1822    var versionTransaction = event.target.transaction;
     
    2226
    2327    request.onerror = function(event) {
    24         debug("put FAILED - " + event);
     28        log("put FAILED - " + event);
    2529        done();
    2630    }
    2731   
    2832    versionTransaction.onabort = function(event) {
    29         debug("versionchange transaction aborted");
     33        log("versionchange transaction aborted");
    3034        done();
    3135    }
    3236
    3337    versionTransaction.oncomplete = function(event) {
    34         debug("versionchange transaction completed");
     38        log("versionchange transaction completed");
    3539        continueTest();
    3640    }
    3741
    3842    versionTransaction.onerror = function(event) {
    39         debug("versionchange transaction error'ed - " + event);
     43        log("versionchange transaction error'ed - " + event);
    4044        done();
    4145    }
     
    5256
    5357    request.onsuccess = function(event) {
    54         debug("Write in readwrite transaction succeeded");
     58        log("Write in readwrite transaction succeeded");
    5559    }
    5660   
    5761    request.onerror = function(event) {
    58         debug("Write in readwrite transaction unexpectedly failed");
     62        log("Write in readwrite transaction unexpectedly failed");
    5963        done();
    6064    }
    6165   
    6266    transaction.onabort = function(event) {
    63         debug("readwrite transaction expectedly aborted");
     67        log("readwrite transaction expectedly aborted");
    6468        done();
    6569    }
    6670
    6771    transaction.oncomplete = function(event) {
    68         debug("readwrite transaction completed");
     72        log("readwrite transaction completed");
    6973        done();
    7074    }
    7175
    7276    transaction.onerror = function(event) {
    73         debug("readwrite transaction error'ed - " + event);
     77        log("readwrite transaction error'ed - " + event);
    7478        done();
    7579    }
     
    8589    request.onsuccess = function(event) {
    8690        if (isFirstTime) {
    87             debug("Starting a readonly transaction");
     91            log("Starting a readonly transaction");
    8892            numberOfOpenTransactions++;
    8993        }
     
    96100
    97101    request.onerror = function(event) {
    98         debug("Unexpected request error - " + event);
     102        log("Unexpected request error - " + event);
    99103        done();
    100104    }
    101105
    102106    transaction.onerror = function(event) {
    103         debug("Unexpected transaction error - " + event);
     107        log("Unexpected transaction error - " + event);
    104108        done();
    105109    }
    106110
    107111    transaction.onabort = function(event) {
    108         --numberOfOpenTransactions;
    109         debug("Unexpected transaction abort - " + event);
     112        log("Unexpected transaction abort - " + event);
    110113        done();
    111114    }
    112115
    113116    transaction.oncomplete = function(event) {
    114         --numberOfOpenTransactions;
    115         debug("readonly transaction completed");
     117        log("readonly transaction completed");
    116118    }
    117119}
  • trunk/Source/WebCore/ChangeLog

    r209068 r209069  
     12016-11-29  Brady Eidson  <beidson@apple.com>
     2
     3        IndexedDB 2.0: Queue up completed requests in the client, handle them one by one.
     4        https://bugs.webkit.org/show_bug.cgi?id=165000
     5
     6        Reviewed by Alex Christensen.
     7
     8        No new tests (Covered extensively by every existing test).
     9
     10        Currently when a TransactionOperation completes on the server, it immediately completes
     11        itself on the client side, including scheduling an event dispatch if necessary.
     12       
     13        This patch changes it so that "server completed operations" instead queue up in the
     14        IDBTransaction and are "client-side completed" asynchronously, 1-by-1.
     15       
     16        Currently this is a "no behavior change" because only one operation is ever sent to
     17        the server at a time.
     18       
     19        But that will change with https://webkit.org/b/164932
     20        And this patch is a pre-requisite for that.
     21       
     22        * Modules/indexeddb/IDBRequest.cpp:
     23        (WebCore::IDBRequest::dispatchEvent):
     24        (WebCore::IDBRequest::didOpenOrIterateCursor):
     25        (WebCore::IDBRequest::completeRequestAndDispatchEvent):
     26        (WebCore::IDBRequest::requestCompleted): Deleted.
     27        * Modules/indexeddb/IDBRequest.h:
     28       
     29        * Modules/indexeddb/IDBTransaction.cpp:
     30        (WebCore::IDBTransaction::IDBTransaction):
     31        (WebCore::IDBTransaction::internalAbort):
     32        (WebCore::IDBTransaction::abortOnServerAndCancelRequests):
     33        (WebCore::IDBTransaction::scheduleOperation):
     34        (WebCore::IDBTransaction::schedulePendingOperationTimer):
     35        (WebCore::IDBTransaction::pendingOperationTimerFired):
     36        (WebCore::IDBTransaction::operationCompletedOnServer):
     37        (WebCore::IDBTransaction::scheduleCompletedOperationTimer):
     38        (WebCore::IDBTransaction::completedOperationTimerFired):
     39        (WebCore::IDBTransaction::completeNoncursorRequest):
     40        (WebCore::IDBTransaction::completeCursorRequest):
     41        (WebCore::IDBTransaction::finishedDispatchEventForRequest):
     42        (WebCore::IDBTransaction::didStart):
     43        (WebCore::IDBTransaction::didOpenCursorOnServer):
     44        (WebCore::IDBTransaction::didIterateCursorOnServer):
     45        (WebCore::IDBTransaction::didGetAllRecordsOnServer):
     46        (WebCore::IDBTransaction::didGetRecordOnServer):
     47        (WebCore::IDBTransaction::didGetCountOnServer):
     48        (WebCore::IDBTransaction::didDeleteRecordOnServer):
     49        (WebCore::IDBTransaction::didClearObjectStoreOnServer):
     50        (WebCore::IDBTransaction::putOrAddOnServer):
     51        (WebCore::IDBTransaction::didPutOrAddOnServer):
     52        (WebCore::IDBTransaction::operationCompletedOnClient):
     53        (WebCore::IDBTransaction::deactivate):
     54        (WebCore::IDBTransaction::connectionClosedFromServer):
     55        (WebCore::IDBTransaction::scheduleOperationTimer): Deleted.
     56        (WebCore::IDBTransaction::operationTimerFired): Deleted.
     57        (WebCore::IDBTransaction::operationDidComplete): Deleted.
     58        * Modules/indexeddb/IDBTransaction.h:
     59       
     60        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
     61        (WebCore::IDBClient::IDBConnectionProxy::completeOperation):
     62       
     63        * Modules/indexeddb/client/TransactionOperation.cpp:
     64        (WebCore::IDBClient::TransactionOperation::TransactionOperation):
     65        * Modules/indexeddb/client/TransactionOperation.h:
     66        (WebCore::IDBClient::TransactionOperation::transitionToCompleteOnThisThread):
     67        (WebCore::IDBClient::TransactionOperation::transitionToComplete):
     68        (WebCore::IDBClient::TransactionOperation::doComplete):
     69        (WebCore::IDBClient::TransactionOperation::idbRequest):
     70        (WebCore::IDBClient::TransactionOperation::performCompleteOnOriginThread): Deleted.
     71        (WebCore::IDBClient::TransactionOperation::completed): Deleted.
     72
    1732016-11-29  Zalan Bujtas  <zalan@apple.com>
    274
  • trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp

    r208306 r209069  
    305305    }
    306306
     307    if (m_transaction)
     308        m_transaction->finishedDispatchEventForRequest(*this);
     309
    307310    return dontPreventDefault;
    308311}
     
    466469    m_pendingCursor = nullptr;
    467470
    468     requestCompleted(resultData);
    469 }
    470 
    471 void IDBRequest::requestCompleted(const IDBResultData& resultData)
     471    completeRequestAndDispatchEvent(resultData);
     472}
     473
     474void IDBRequest::completeRequestAndDispatchEvent(const IDBResultData& resultData)
    472475{
    473476    ASSERT(currentThread() == originThreadID());
  • trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h

    r208476 r209069  
    8888    using RefCounted::deref;
    8989
    90     void requestCompleted(const IDBResultData&);
     90    void completeRequestAndDispatchEvent(const IDBResultData&);
    9191
    9292    void setResult(const IDBKeyData&);
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp

    r208985 r209069  
    7575    , m_database(database)
    7676    , m_info(info)
    77     , m_operationTimer(*this, &IDBTransaction::operationTimerFired)
     77    , m_pendingOperationTimer(*this, &IDBTransaction::pendingOperationTimerFired)
     78    , m_completedOperationTimer(*this, &IDBTransaction::completedOperationTimerFired)
    7879    , m_openDBRequest(request)
     80    , m_currentlyCompletingRequest(request)
    7981
    8082{
     
    245247    transitionedToFinishing(IndexedDB::TransactionState::Aborting);
    246248   
    247     m_abortQueue.swap(m_transactionOperationQueue);
     249    m_abortQueue.swap(m_pendingTransactionOperationQueue);
    248250
    249251    scheduleOperation(IDBClient::createTransactionOperation(*this, nullptr, &IDBTransaction::abortOnServerAndCancelRequests));
     
    254256    LOG(IndexedDB, "IDBTransaction::abortOnServerAndCancelRequests");
    255257    ASSERT(currentThread() == m_database->originThreadID());
    256     ASSERT(m_transactionOperationQueue.isEmpty());
     258    ASSERT(m_pendingTransactionOperationQueue.isEmpty());
    257259
    258260    m_database->connectionProxy().abortTransaction(*this);
     
    261263    m_transactionOperationMap.remove(operation.identifier());
    262264
     265    m_currentlyCompletingRequest = nullptr;
     266   
    263267    IDBError error(IDBDatabaseException::AbortError);
    264     for (auto& operation : m_abortQueue)
    265         operation->completed(IDBResultData::error(operation->identifier(), error));
     268    for (auto& operation : m_abortQueue) {
     269        m_currentlyCompletingRequest = nullptr;
     270        operation->doComplete(IDBResultData::error(operation->identifier(), error));
     271    }
    266272
    267273    // Since we're aborting, it should be impossible to have queued any further operations.
    268     ASSERT(m_transactionOperationQueue.isEmpty());
     274    ASSERT(m_pendingTransactionOperationQueue.isEmpty());
    269275}
    270276
     
    340346    ASSERT(currentThread() == m_database->originThreadID());
    341347
    342     m_transactionOperationQueue.append(operation);
     348    m_pendingTransactionOperationQueue.append(operation);
    343349    m_transactionOperationMap.set(operation->identifier(), WTFMove(operation));
    344350
    345     scheduleOperationTimer();
    346 }
    347 
    348 void IDBTransaction::scheduleOperationTimer()
    349 {
    350     ASSERT(currentThread() == m_database->originThreadID());
    351 
    352     if (!m_operationTimer.isActive())
    353         m_operationTimer.startOneShot(0);
    354 }
    355 
    356 void IDBTransaction::operationTimerFired()
    357 {
    358     LOG(IndexedDB, "IDBTransaction::operationTimerFired (%p)", this);
     351    schedulePendingOperationTimer();
     352}
     353
     354void IDBTransaction::schedulePendingOperationTimer()
     355{
     356    ASSERT(currentThread() == m_database->originThreadID());
     357
     358    if (!m_pendingOperationTimer.isActive())
     359        m_pendingOperationTimer.startOneShot(0);
     360}
     361
     362void IDBTransaction::pendingOperationTimerFired()
     363{
     364    LOG(IndexedDB, "IDBTransaction::pendingOperationTimerFired (%p)", this);
    359365    ASSERT(currentThread() == m_database->originThreadID());
    360366
     
    362368        return;
    363369
    364     if (!m_transactionOperationQueue.isEmpty()) {
    365         auto operation = m_transactionOperationQueue.takeFirst();
     370    if (!m_pendingTransactionOperationQueue.isEmpty()) {
     371        auto operation = m_pendingTransactionOperationQueue.takeFirst();
    366372        operation->perform();
    367373
     
    374380    if (!isFinishedOrFinishing())
    375381        commit();
     382}
     383
     384void IDBTransaction::operationCompletedOnServer(const IDBResultData& data, IDBClient::TransactionOperation& operation)
     385{
     386    ASSERT(currentThread() == m_database->originThreadID());
     387    ASSERT(currentThread() == operation.originThreadID());
     388
     389    m_completedOnServerQueue.append({ &operation, data });
     390    scheduleCompletedOperationTimer();
     391}
     392
     393void IDBTransaction::scheduleCompletedOperationTimer()
     394{
     395    ASSERT(currentThread() == m_database->originThreadID());
     396
     397    if (!m_completedOperationTimer.isActive())
     398        m_completedOperationTimer.startOneShot(0);
     399}
     400
     401void IDBTransaction::completedOperationTimerFired()
     402{
     403    LOG(IndexedDB, "IDBTransaction::completedOperationTimerFired (%p)", this);
     404    ASSERT(currentThread() == m_database->originThreadID());
     405
     406    if (m_completedOnServerQueue.isEmpty() || m_currentlyCompletingRequest)
     407        return;
     408
     409    auto iterator = m_completedOnServerQueue.takeFirst();
     410    iterator.first->doComplete(iterator.second);
     411
     412    if (!m_completedOnServerQueue.isEmpty() && !m_currentlyCompletingRequest)
     413        scheduleCompletedOperationTimer();
     414}
     415
     416void IDBTransaction::completeNoncursorRequest(IDBRequest& request, const IDBResultData& result)
     417{
     418    ASSERT(!m_currentlyCompletingRequest);
     419
     420    request.completeRequestAndDispatchEvent(result);
     421
     422    m_currentlyCompletingRequest = &request;
     423}
     424
     425void IDBTransaction::completeCursorRequest(IDBRequest& request, const IDBResultData& result)
     426{
     427    ASSERT(!m_currentlyCompletingRequest);
     428
     429    request.didOpenOrIterateCursor(result);
     430
     431    m_currentlyCompletingRequest = &request;
     432}
     433
     434void IDBTransaction::finishedDispatchEventForRequest(IDBRequest& request)
     435{
     436    if (isFinishedOrFinishing())
     437        return;
     438
     439    ASSERT_UNUSED(request, !m_currentlyCompletingRequest || m_currentlyCompletingRequest == &request);
     440
     441    m_currentlyCompletingRequest = nullptr;
     442    scheduleCompletedOperationTimer();
    376443}
    377444
     
    423490    }
    424491
    425     scheduleOperationTimer();
     492    schedulePendingOperationTimer();
    426493}
    427494
     
    725792    ASSERT(currentThread() == m_database->originThreadID());
    726793
    727     request.didOpenOrIterateCursor(resultData);
     794    completeCursorRequest(request, resultData);
    728795}
    729796
     
    754821    ASSERT(currentThread() == m_database->originThreadID());
    755822
    756     request.didOpenOrIterateCursor(resultData);
     823    completeCursorRequest(request, resultData);
    757824}
    758825
     
    807874
    808875    if (resultData.type() == IDBResultType::Error) {
    809         request.requestCompleted(resultData);
     876        completeNoncursorRequest(request, resultData);
    810877        return;
    811878    }
     
    823890    }
    824891
    825     request.requestCompleted(resultData);
     892    completeNoncursorRequest(request, resultData);
    826893}
    827894
     
    891958
    892959    if (resultData.type() == IDBResultType::Error) {
    893         request.requestCompleted(resultData);
     960        completeNoncursorRequest(request, resultData);
    894961        return;
    895962    }
     
    911978    }
    912979
    913     request.requestCompleted(resultData);
     980    completeNoncursorRequest(request, resultData);
    914981}
    915982
     
    9621029
    9631030    request.setResult(resultData.resultInteger());
    964     request.requestCompleted(resultData);
     1031    completeNoncursorRequest(request, resultData);
    9651032}
    9661033
     
    9951062
    9961063    request.setResultToUndefined();
    997     request.requestCompleted(resultData);
     1064    completeNoncursorRequest(request, resultData);
    9981065}
    9991066
     
    10291096
    10301097    request.setResultToUndefined();
    1031     request.requestCompleted(resultData);
     1098    completeNoncursorRequest(request, resultData);
    10321099}
    10331100
     
    10751142            auto result = IDBResultData::error(operation.identifier(), { IDBDatabaseException::UnknownError, ASCIILiteral("Error preparing Blob/File data to be stored in object store") });
    10761143            scriptExecutionContext()->postTask([protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)](ScriptExecutionContext&) {
    1077                 protectedOperation->completed(result);
     1144                protectedOperation->doComplete(result);
    10781145            });
    10791146        }
     
    10931160        auto result = IDBResultData::error(protectedOperation->identifier(), { IDBDatabaseException::UnknownError, ASCIILiteral("Error preparing Blob/File data to be stored in object store") });
    10941161        callOnMainThread([protectedThis = WTFMove(protectedThis), protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)]() mutable {
    1095             protectedOperation->completed(result);
     1162            protectedOperation->doComplete(result);
    10961163        });
    10971164    });
     
    11071174    else
    11081175        request.setResultToUndefined();
    1109     request.requestCompleted(resultData);
     1176    completeNoncursorRequest(request, resultData);
    11101177}
    11111178
     
    11681235}
    11691236
    1170 void IDBTransaction::operationDidComplete(IDBClient::TransactionOperation& operation)
    1171 {
     1237void IDBTransaction::operationCompletedOnClient(IDBClient::TransactionOperation& operation)
     1238{
     1239    LOG(IndexedDB, "IDBTransaction::operationCompletedOnClient");
     1240
    11721241    ASSERT(m_transactionOperationMap.get(operation.identifier()) == &operation);
    11731242    ASSERT(currentThread() == m_database->originThreadID());
     
    11761245    m_transactionOperationMap.remove(operation.identifier());
    11771246
    1178     scheduleOperationTimer();
     1247    schedulePendingOperationTimer();
    11791248}
    11801249
     
    12041273        m_state = IndexedDB::TransactionState::Inactive;
    12051274
    1206     scheduleOperationTimer();
     1275    schedulePendingOperationTimer();
    12071276}
    12081277
     
    12161285    copyValuesToVector(m_transactionOperationMap, operations);
    12171286
    1218     for (auto& operation : operations)
    1219         operation->completed(IDBResultData::error(operation->identifier(), error));
     1287    for (auto& operation : operations) {
     1288        m_currentlyCompletingRequest = nullptr;
     1289        operation->doComplete(IDBResultData::error(operation->identifier(), error));
     1290    }
    12201291
    12211292    connectionProxy().forgetActiveOperations(operations);
    12221293
    1223     m_transactionOperationQueue.clear();
     1294    m_pendingTransactionOperationQueue.clear();
    12241295    m_abortQueue.clear();
    12251296    m_transactionOperationMap.clear();
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h

    r208985 r209069  
    139139    void deactivate();
    140140
    141     void operationDidComplete(IDBClient::TransactionOperation&);
     141    void operationCompletedOnServer(const IDBResultData&, IDBClient::TransactionOperation&);
     142    void operationCompletedOnClient(IDBClient::TransactionOperation&);
     143
     144    void finishedDispatchEventForRequest(IDBRequest&);
    142145
    143146    bool isFinishedOrFinishing() const;
     
    160163
    161164    void scheduleOperation(RefPtr<IDBClient::TransactionOperation>&&);
    162     void operationTimerFired();
     165    void pendingOperationTimerFired();
     166    void completedOperationTimerFired();
    163167
    164168    void fireOnComplete();
     
    218222    void establishOnServer();
    219223
    220     void scheduleOperationTimer();
     224    void completeNoncursorRequest(IDBRequest&, const IDBResultData&);
     225    void completeCursorRequest(IDBRequest&, const IDBResultData&);
     226
     227    void schedulePendingOperationTimer();
     228    void scheduleCompletedOperationTimer();
    221229
    222230    Ref<IDBDatabase> m_database;
     
    229237    RefPtr<DOMError> m_domError;
    230238
    231     Timer m_operationTimer;
     239    Timer m_pendingOperationTimer;
     240    Timer m_completedOperationTimer;
    232241    std::unique_ptr<Timer> m_activationTimer;
    233242
    234243    RefPtr<IDBOpenDBRequest> m_openDBRequest;
    235244
    236     Deque<RefPtr<IDBClient::TransactionOperation>> m_transactionOperationQueue;
     245    Deque<RefPtr<IDBClient::TransactionOperation>> m_pendingTransactionOperationQueue;
     246    Deque<std::pair<RefPtr<IDBClient::TransactionOperation>, IDBResultData>> m_completedOnServerQueue;
    237247    Deque<RefPtr<IDBClient::TransactionOperation>> m_abortQueue;
    238248    HashMap<IDBResourceIdentifier, RefPtr<IDBClient::TransactionOperation>> m_transactionOperationMap;
     
    243253
    244254    HashSet<RefPtr<IDBRequest>> m_openRequests;
     255    RefPtr<IDBRequest> m_currentlyCompletingRequest;
    245256
    246257    bool m_contextStopped { false };
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp

    r208609 r209069  
    250250        return;
    251251
    252     operation->performCompleteOnOriginThread(resultData, WTFMove(operation));
     252    operation->transitionToComplete(resultData, WTFMove(operation));
    253253}
    254254
  • trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp

    r205462 r209069  
    4444    if (auto* cursor = request.pendingCursor())
    4545        m_cursorIdentifier = std::make_unique<IDBResourceIdentifier>(cursor->info().identifier());
     46
     47    m_idbRequest = &request;
    4648}
    4749
  • trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h

    r208646 r209069  
    6262    }
    6363
    64     void performCompleteOnOriginThread(const IDBResultData& data, RefPtr<TransactionOperation>&& lastRef)
     64    void transitionToCompleteOnThisThread(const IDBResultData& data)
     65    {
     66        ASSERT(m_originThreadID == currentThread());
     67        m_transaction->operationCompletedOnServer(data, *this);
     68    }
     69
     70    void transitionToComplete(const IDBResultData& data, RefPtr<TransactionOperation>&& lastRef)
    6571    {
    6672        ASSERT(isMainThread());
    6773
    6874        if (m_originThreadID == currentThread())
    69             completed(data);
     75            transitionToCompleteOnThisThread(data);
    7076        else {
    71             m_transaction->performCallbackOnOriginThread(*this, &TransactionOperation::completed, data);
     77            m_transaction->performCallbackOnOriginThread(*this, &TransactionOperation::transitionToCompleteOnThisThread, data);
    7278            m_transaction->callFunctionOnOriginThread([lastRef = WTFMove(lastRef)]() {
    7379            });
     
    7581    }
    7682
    77     void completed(const IDBResultData& data)
     83    void doComplete(const IDBResultData& data)
    7884    {
    7985        ASSERT(m_originThreadID == currentThread());
    8086        ASSERT(m_completeFunction);
    8187        m_completeFunction(data);
    82         m_transaction->operationDidComplete(*this);
     88        m_transaction->operationCompletedOnClient(*this);
    8389
    8490        // m_completeFunction might be holding the last ref to this TransactionOperation,
     
    9197
    9298    ThreadIdentifier originThreadID() const { return m_originThreadID; }
     99
     100    IDBRequest* idbRequest() { return m_idbRequest.get(); }
    93101
    94102protected:
     
    119127
    120128    ThreadIdentifier m_originThreadID { currentThread() };
     129    RefPtr<IDBRequest> m_idbRequest;
    121130};
    122131
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp

    r208985 r209069  
    808808    }
    809809
    810 
    811     if (transaction->mode() == IDBTransactionMode::Versionchange) {
    812         ASSERT(m_originalDatabaseInfoBeforeVersionChange);
     810    if (transaction->mode() == IDBTransactionMode::Versionchange && m_originalDatabaseInfoBeforeVersionChange)
    813811        m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange);
    814     }
    815812
    816813    return transaction->abort();
Note: See TracChangeset for help on using the changeset viewer.