Changeset 135332 in webkit


Ignore:
Timestamp:
Nov 20, 2012, 4:35:09 PM (12 years ago)
Author:
jsbell@chromium.org
Message:

IndexedDB: Move control of transaction completion to front end
https://bugs.webkit.org/show_bug.cgi?id=100903

Reviewed by Tony Chang.

"When a transaction can no longer become active, the implementation must attempt to
commit it" - that is, all requests have dispatched success/error events and no further
requests have been made. Previously, this was done by the back end waiting for events
from the front end, but the front end can more efficiently make the decision.

There should be no detectable behavior change.

Tests: storage/indexeddb/transaction-*.html

  • Modules/indexeddb/IDBTransaction.cpp:

(WebCore::IDBTransaction::IDBTransaction):
(WebCore::IDBTransaction::setActive):
(WebCore::IDBTransaction::registerRequest):

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

(WebCore::IDBTransactionBackendImpl::hasPendingTasks): Added.
(WebCore::IDBTransactionBackendImpl::didCompleteTaskEvents):
(WebCore::IDBTransactionBackendImpl::run):
(WebCore::IDBTransactionBackendImpl::taskEventTimerFired):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r135329 r135332  
     12012-11-20  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Move control of transaction completion to front end
     4        https://bugs.webkit.org/show_bug.cgi?id=100903
     5
     6        Reviewed by Tony Chang.
     7
     8        "When a transaction can no longer become active, the implementation must attempt to
     9        commit it" - that is, all requests have dispatched success/error events and no further
     10        requests have been made. Previously, this was done by the back end waiting for events
     11        from the front end, but the front end can more efficiently make the decision.
     12
     13        There should be no detectable behavior change.
     14
     15        Tests: storage/indexeddb/transaction-*.html
     16
     17        * Modules/indexeddb/IDBTransaction.cpp:
     18        (WebCore::IDBTransaction::IDBTransaction):
     19        (WebCore::IDBTransaction::setActive):
     20        (WebCore::IDBTransaction::registerRequest):
     21        * Modules/indexeddb/IDBTransaction.h:
     22        * Modules/indexeddb/IDBTransactionBackendImpl.cpp:
     23        (WebCore::IDBTransactionBackendImpl::hasPendingTasks): Added.
     24        (WebCore::IDBTransactionBackendImpl::didCompleteTaskEvents):
     25        (WebCore::IDBTransactionBackendImpl::run):
     26        (WebCore::IDBTransactionBackendImpl::taskEventTimerFired):
     27
    1282012-11-20  Kentaro Hara  <haraken@chromium.org>
    229
  • trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp

    r134989 r135332  
    501501
    502502    bool dontPreventDefault = IDBEventDispatcher::dispatch(event.get(), targets);
     503
     504    if (m_transaction && m_readyState == DONE)
     505        m_transaction->unregisterRequest(this);
     506
     507    // If this was the last request in the transaction's list, it may commit here.
    503508    if (setTransactionActive)
    504509        m_transaction->setActive(false);
     
    519524        if (event->type() != eventNames().blockedEvent)
    520525            m_transaction->backend()->didCompleteTaskEvents();
    521 
    522         if (m_readyState == DONE)
    523             m_transaction->unregisterRequest(this);
    524526    }
    525527
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp

    r135308 r135332  
    9696    , m_openDBRequest(openDBRequest)
    9797    , m_mode(mode)
    98     , m_active(true)
    99     , m_state(Unused)
     98    , m_state(Active)
    10099    , m_hasPendingActivity(true)
    101100    , m_contextStopped(false)
     
    105104    if (mode == VERSION_CHANGE) {
    106105        // Not active until the callback.
    107         m_active = false;
    108         // Implicitly used by the version change itself.
    109         m_state = Used;
     106        m_state = Inactive;
    110107    }
    111108
    112109    // We pass a reference of this object before it can be adopted.
    113110    relaxAdoptionRequirement();
    114     if (m_active)
     111    if (m_state == Active)
    115112        IDBPendingTransactionMonitor::addNewTransaction(this);
    116113    m_database->transactionCreated(this);
     
    207204    if (m_state == Finishing)
    208205        return;
    209     ASSERT(m_state == Unused || m_state == Used);
    210     ASSERT(active != m_active);
    211     m_active = active;
    212 
    213     if (!active && m_state == Unused)
     206    ASSERT(active != (m_state == Active));
     207    m_state = active ? Active : Inactive;
     208
     209    if (!active && m_requestList.isEmpty())
    214210        m_backend->commit();
    215211}
     
    223219
    224220    m_state = Finishing;
    225     m_active = false;
    226221
    227222    while (!m_requestList.isEmpty()) {
     
    279274{
    280275    ASSERT(request);
    281     ASSERT(m_state == Unused || m_state == Used);
    282     ASSERT(m_active);
     276    ASSERT(m_state == Active);
    283277    m_requestList.add(request);
    284     m_state = Used;
    285278}
    286279
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h

    r134040 r135332  
    7171
    7272    IDBTransactionBackendInterface* backend() const;
    73     bool isActive() const { return m_active; }
     73    bool isActive() const { return m_state == Active; }
    7474    bool isFinished() const { return m_state == Finished; }
    7575    bool isReadOnly() const { return m_mode == READ_ONLY; }
     
    138138
    139139    enum State {
    140         Unused, // No requests have been made.
    141         Used, // At least one request has been made.
     140        Inactive, // Created or started, but not in an event callback
     141        Active, // Created or started, in creation scope or an event callback
    142142        Finishing, // In the process of aborting or completing.
    143143        Finished, // No more events will fire and no new requests may be filed.
     
    149149    IDBOpenDBRequest* m_openDBRequest;
    150150    const Mode m_mode;
    151     bool m_active;
    152151    State m_state;
    153152    bool m_hasPendingActivity;
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.cpp

    r134968 r135332  
    152152}
    153153
     154bool IDBTransactionBackendImpl::hasPendingTasks() const
     155{
     156    return m_pendingEvents || m_pendingPreemptiveEvents || !isTaskQueueEmpty();
     157}
     158
    154159void IDBTransactionBackendImpl::registerOpenCursor(IDBCursorBackendImpl* cursor)
    155160{
     
    177182    m_pendingEvents--;
    178183
     184    // A single task has completed and error/success events fired. Schedule
     185    // timer to process another.
    179186    if (!m_taskEventTimer.isActive())
    180187        m_taskEventTimer.startOneShot(0);
     
    183190void IDBTransactionBackendImpl::run()
    184191{
     192    // TransactionCoordinator has started this transaction. Schedule a timer
     193    // to process the first task.
    185194    ASSERT(m_state == StartPending || m_state == Running);
    186195    ASSERT(!m_taskTimer.isActive());
     
    201210{
    202211    IDB_TRACE("IDBTransactionBackendImpl::commit");
     212
     213    ASSERT(m_state == Unused || m_state == Running);
     214
     215    // Front-end has requested a commit, but there may be tasks like createIndex which
     216    // are considered synchronous by the front-end but are processed asynchronously.
     217    if (hasPendingTasks())
     218        return;
     219
    203220    // The last reference to this object may be released while performing the
    204221    // commit steps below. We therefore take a self reference to keep ourselves
    205222    // alive while executing this method.
    206223    RefPtr<IDBTransactionBackendImpl> protect(this);
    207     ASSERT(m_state == Unused || m_state == Running);
    208     ASSERT(isTaskQueueEmpty());
    209224
    210225    bool unused = m_state == Unused;
     
    268283    ASSERT(m_state == Running);
    269284
    270     if (!m_pendingEvents && !m_pendingPreemptiveEvents && isTaskQueueEmpty()) {
     285    if (!hasPendingTasks()) {
    271286        // The last task event has completed and the task
    272287        // queue is empty. Commit the transaction.
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.h

    r134129 r135332  
    7575    enum State {
    7676        Unused, // Created, but no tasks yet.
    77         StartPending, // Enqueued tasks, but SQLite transaction not yet started.
    78         Running, // SQLite transaction started but not yet finished.
     77        StartPending, // Enqueued tasks, but backing store transaction not yet started.
     78        Running, // Backing store transaction started but not yet finished.
    7979        Finished, // Either aborted or committed.
    8080    };
     
    8484
    8585    bool isTaskQueueEmpty() const;
     86    bool hasPendingTasks() const;
    8687
    8788    void taskTimerFired(Timer<IDBTransactionBackendImpl>*);
Note: See TracChangeset for help on using the changeset viewer.