Changeset 135927 in webkit


Ignore:
Timestamp:
Nov 27, 2012, 3:08:17 PM (12 years ago)
Author:
jsbell@chromium.org
Message:

IndexedDB: Simplify transaction timers and event tracking
https://bugs.webkit.org/show_bug.cgi?id=102984

Reviewed by Tony Chang.

Source/WebCore:

Now that the transaction "commit" decision is made on the front-end, the back end no-longer
needs to be aware of when individual IDBRequests have dispatched to script or track pending
events (except for preemptive ones like createIndex). This also lets two timers be collapsed
into one which significantly simplifies the code flow in IDBTransactionBackendImpl.

No new tests - just simplification. Exercised by storage/indexeddb/transaction-*.html etc.

  • Modules/indexeddb/IDBCursorBackendImpl.cpp:

(WebCore::IDBCursorBackendImpl::prefetchContinueInternal): No more tracking.
(WebCore::IDBCursorBackendImpl::prefetchReset): No more tracking.

  • Modules/indexeddb/IDBDatabaseBackendImpl.cpp:

(WebCore::IDBDatabaseBackendImpl::createObjectStoreInternal): No more tracking.
(WebCore::IDBDatabaseBackendImpl::deleteObjectStoreInternal): No more tracking.

  • Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:

(WebCore::IDBObjectStoreBackendImpl::setIndexesReadyInternal): No more tracking.
(WebCore::IDBObjectStoreBackendImpl::createIndexInternal): No more tracking.
(WebCore::IDBObjectStoreBackendImpl::deleteIndexInternal): No more tracking.

  • Modules/indexeddb/IDBRequest.cpp:

(WebCore::IDBRequest::dispatchEvent): Order must be:

  1. request is unregistered from transaction (so request list may be empty)
  2. abort transaction if event being dispatched was an error
  3. deactivate transaction (which may commit if #1 left it empty and #2 didn't abort)
  • Modules/indexeddb/IDBTransactionBackendImpl.cpp:

(WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl): Need to track if commit
was requested; previously the front end would have triggered an event timer which, on
completion, would be the signal that the front end was finished.
(WebCore::IDBTransactionBackendImpl::scheduleTask): Schedule a timer to service the new
task, if necessary.
(WebCore::IDBTransactionBackendImpl::abort):
(WebCore::IDBTransactionBackendImpl::hasPendingTasks):
(WebCore::IDBTransactionBackendImpl::commit):
(WebCore::IDBTransactionBackendImpl::taskTimerFired): Picks up "commit" responsibilities
from the now deleted taskEventTimerFired, if everything is truly complete done.

  • Modules/indexeddb/IDBTransactionBackendImpl.h:

(IDBTransactionBackendImpl):

  • Modules/indexeddb/IDBTransactionBackendInterface.h:

(WebCore::IDBTransactionBackendInterface::didCompleteTaskEvents): Removed from interface.

Source/WebKit/chromium:

Remove now-unused didCompleteTaskEvents() method.

  • src/IDBTransactionBackendProxy.cpp:
  • src/IDBTransactionBackendProxy.h:

(IDBTransactionBackendProxy):

  • src/WebIDBTransactionImpl.cpp:
  • src/WebIDBTransactionImpl.h:
Location:
trunk/Source
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r135922 r135927  
     12012-11-27  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Simplify transaction timers and event tracking
     4        https://bugs.webkit.org/show_bug.cgi?id=102984
     5
     6        Reviewed by Tony Chang.
     7
     8        Now that the transaction "commit" decision is made on the front-end, the back end no-longer
     9        needs to be aware of when individual IDBRequests have dispatched to script or track pending
     10        events (except for preemptive ones like createIndex). This also lets two timers be collapsed
     11        into one which significantly simplifies the code flow in IDBTransactionBackendImpl.
     12
     13        No new tests - just simplification. Exercised by storage/indexeddb/transaction-*.html etc.
     14
     15        * Modules/indexeddb/IDBCursorBackendImpl.cpp:
     16        (WebCore::IDBCursorBackendImpl::prefetchContinueInternal): No more tracking.
     17        (WebCore::IDBCursorBackendImpl::prefetchReset): No more tracking.
     18        * Modules/indexeddb/IDBDatabaseBackendImpl.cpp:
     19        (WebCore::IDBDatabaseBackendImpl::createObjectStoreInternal): No more tracking.
     20        (WebCore::IDBDatabaseBackendImpl::deleteObjectStoreInternal): No more tracking.
     21        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
     22        (WebCore::IDBObjectStoreBackendImpl::setIndexesReadyInternal): No more tracking.
     23        (WebCore::IDBObjectStoreBackendImpl::createIndexInternal): No more tracking.
     24        (WebCore::IDBObjectStoreBackendImpl::deleteIndexInternal): No more tracking.
     25        * Modules/indexeddb/IDBRequest.cpp:
     26        (WebCore::IDBRequest::dispatchEvent): Order must be:
     27        1. request is unregistered from transaction (so request list may be empty)
     28        2. abort transaction if event being dispatched was an error
     29        3. deactivate transaction (which may commit if #1 left it empty and #2 didn't abort)
     30        * Modules/indexeddb/IDBTransactionBackendImpl.cpp:
     31        (WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl): Need to track if commit
     32        was requested; previously the front end would have triggered an event timer which, on
     33        completion, would be the signal that the front end was finished.
     34        (WebCore::IDBTransactionBackendImpl::scheduleTask): Schedule a timer to service the new
     35        task, if necessary.
     36        (WebCore::IDBTransactionBackendImpl::abort):
     37        (WebCore::IDBTransactionBackendImpl::hasPendingTasks):
     38        (WebCore::IDBTransactionBackendImpl::commit):
     39        (WebCore::IDBTransactionBackendImpl::taskTimerFired): Picks up "commit" responsibilities
     40        from the now deleted taskEventTimerFired, if everything is truly complete done.
     41        * Modules/indexeddb/IDBTransactionBackendImpl.h:
     42        (IDBTransactionBackendImpl):
     43        * Modules/indexeddb/IDBTransactionBackendInterface.h:
     44        (WebCore::IDBTransactionBackendInterface::didCompleteTaskEvents): Removed from interface.
     45
    1462012-11-27  Kentaro Hara  <haraken@chromium.org>
    247
  • trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp

    r133858 r135927  
    174174    }
    175175
    176     cursor->m_transaction->addPendingEvents(foundKeys.size() - 1);
    177176    callbacks->onSuccessWithPrefetch(foundKeys, foundPrimaryKeys, foundValues);
    178177}
     
    181180{
    182181    IDB_TRACE("IDBCursorBackendImpl::prefetchReset");
    183     m_transaction->addPendingEvents(-unusedPrefetches);
    184182    m_cursor = m_savedCursor;
    185183    m_savedCursor = 0;
  • trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp

    r135904 r135927  
    181181        return;
    182182    }
    183 
    184     transaction->didCompleteTaskEvents();
    185183}
    186184
     
    211209{
    212210    database->m_backingStore->deleteObjectStore(transaction->backingStoreTransaction(), database->id(), objectStore->id());
    213     transaction->didCompleteTaskEvents();
    214211}
    215212
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp

    r135177 r135927  
    269269    for (size_t i = 0; i < indexIds->size(); ++i)
    270270        transaction->didCompletePreemptiveEvent();
    271     transaction->didCompleteTaskEvents();
    272271}
    273272
     
    408407        return;
    409408    }
    410 
    411     transaction->didCompleteTaskEvents();
    412409}
    413410
     
    440437{
    441438    objectStore->backingStore()->deleteIndex(transaction->backingStoreTransaction(), objectStore->databaseId(), objectStore->id(), index->id());
    442     transaction->didCompleteTaskEvents();
    443439}
    444440
  • trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp

    r135904 r135927  
    7979    , m_requestState(context)
    8080{
    81     if (m_transaction) {
     81    // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) are not
     82    // associated with transactions.
     83    if (m_transaction)
    8284        m_transaction->registerRequest(this);
    83     }
    8485}
    8586
     
    477478    bool dontPreventDefault = IDBEventDispatcher::dispatch(event.get(), targets);
    478479
    479     if (m_transaction && m_readyState == DONE)
    480         m_transaction->unregisterRequest(this);
    481 
    482     // If this was the last request in the transaction's list, it may commit here.
    483     if (setTransactionActive)
    484         m_transaction->setActive(false);
    485 
    486     if (cursorToNotify)
    487         cursorToNotify->postSuccessHandlerCallback();
    488 
    489     if (m_readyState == DONE && (!cursorToNotify || m_cursorFinished) && event->type() != eventNames().upgradeneededEvent)
    490         m_hasPendingActivity = false;
    491 
    492480    if (m_transaction) {
     481        if (m_readyState == DONE)
     482            m_transaction->unregisterRequest(this);
     483
     484        // Possibly abort the transaction. This must occur after unregistering (so this request
     485        // doesn't receive a second error) and before deactivating (which might trigger commit).
    493486        if (event->type() == eventNames().errorEvent && dontPreventDefault && !m_requestAborted) {
    494487            m_transaction->setError(m_error);
     
    497490        }
    498491
    499         if (event->type() != eventNames().blockedEvent)
    500             m_transaction->backend()->didCompleteTaskEvents();
    501     }
     492        // If this was the last request in the transaction's list, it may commit here.
     493        if (setTransactionActive)
     494            m_transaction->setActive(false);
     495    }
     496
     497    if (cursorToNotify)
     498        cursorToNotify->postSuccessHandlerCallback();
     499
     500    if (m_readyState == DONE && (!cursorToNotify || m_cursorFinished) && event->type() != eventNames().upgradeneededEvent)
     501        m_hasPendingActivity = false;
    502502
    503503    return dontPreventDefault;
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.cpp

    r135856 r135927  
    5050    , m_mode(mode)
    5151    , m_state(Unused)
     52    , m_commitPending(false)
    5253    , m_database(database)
    5354    , m_transaction(database->backingStore().get())
    5455    , m_taskTimer(this, &IDBTransactionBackendImpl::taskTimerFired)
    55     , m_taskEventTimer(this, &IDBTransactionBackendImpl::taskEventTimerFired)
    5656    , m_pendingPreemptiveEvents(0)
    57     , m_pendingEvents(0)
    5857{
    5958    m_database->transactionCoordinator()->didCreateTransaction(this);
     
    9392    if (m_state == Unused)
    9493        start();
     94    else if (m_state == Running && !m_taskTimer.isActive())
     95        m_taskTimer.startOneShot(0);
    9596
    9697    return true;
     
    117118    m_state = Finished;
    118119    m_taskTimer.stop();
    119     m_taskEventTimer.stop();
    120120
    121121    if (wasRunning)
     
    155155bool IDBTransactionBackendImpl::hasPendingTasks() const
    156156{
    157     return m_pendingEvents || m_pendingPreemptiveEvents || !isTaskQueueEmpty();
     157    return m_pendingPreemptiveEvents || !isTaskQueueEmpty();
    158158}
    159159
     
    166166{
    167167    m_openCursors.remove(cursor);
    168 }
    169 
    170 void IDBTransactionBackendImpl::addPendingEvents(int n)
    171 {
    172     m_pendingEvents += n;
    173     ASSERT(m_pendingEvents >= 0);
    174 }
    175 
    176 void IDBTransactionBackendImpl::didCompleteTaskEvents()
    177 {
    178     if (m_state == Finished)
    179         return;
    180 
    181     ASSERT(m_state == Running);
    182     ASSERT(m_pendingEvents);
    183     m_pendingEvents--;
    184 
    185     // A single task has completed and error/success events fired. Schedule
    186     // timer to process another.
    187     if (!m_taskEventTimer.isActive())
    188         m_taskEventTimer.startOneShot(0);
    189168}
    190169
     
    213192
    214193    ASSERT(m_state == Unused || m_state == Running);
     194    m_commitPending = true;
    215195
    216196    // Front-end has requested a commit, but there may be tasks like createIndex which
     
    271251        ASSERT(m_state == Running);
    272252        OwnPtr<ScriptExecutionContext::Task> task(taskQueue->takeFirst());
    273         m_pendingEvents++;
    274253        task->performTask(0);
    275254
     
    277256        taskQueue = m_pendingPreemptiveEvents ? &m_preemptiveTaskQueue : &m_taskQueue;
    278257    }
    279 }
    280 
    281 void IDBTransactionBackendImpl::taskEventTimerFired(Timer<IDBTransactionBackendImpl>*)
    282 {
    283     IDB_TRACE("IDBTransactionBackendImpl::taskEventTimerFired");
    284     ASSERT(m_state == Running);
    285 
    286     if (!hasPendingTasks()) {
    287         // The last task event has completed and the task
    288         // queue is empty. Commit the transaction.
     258
     259    // If there are no pending tasks, we haven't already committed/aborted,
     260    // and the front-end requested a commit, it is now safe to do so.
     261    if (!hasPendingTasks() && m_state != Finished && m_commitPending)
    289262        commit();
    290         return;
    291     }
    292 
    293     // We are still waiting for other events to complete. However,
    294     // the task queue is non-empty and the timer is inactive.
    295     // We can therfore schedule the timer again.
    296     if (!isTaskQueueEmpty() && !m_taskTimer.isActive())
    297         m_taskTimer.startOneShot(0);
    298263}
    299264
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.h

    r135856 r135927  
    5454    // IDBTransactionBackendInterface
    5555    virtual PassRefPtr<IDBObjectStoreBackendInterface> objectStore(int64_t, ExceptionCode&);
    56     virtual void didCompleteTaskEvents();
    5756    virtual void abort();
    5857    virtual void setCallbacks(IDBTransactionCallbacks* callbacks) { m_callbacks = callbacks; }
     
    6564    void registerOpenCursor(IDBCursorBackendImpl*);
    6665    void unregisterOpenCursor(IDBCursorBackendImpl*);
    67     void addPendingEvents(int);
    6866    void addPreemptiveEvent() { m_pendingPreemptiveEvents++; }
    6967    void didCompletePreemptiveEvent() { m_pendingPreemptiveEvents--; ASSERT(m_pendingPreemptiveEvents >= 0); }
     
    8886
    8987    void taskTimerFired(Timer<IDBTransactionBackendImpl>*);
    90     void taskEventTimerFired(Timer<IDBTransactionBackendImpl>*);
    9188    void closeOpenCursors();
    9289
     
    9693
    9794    State m_state;
     95    bool m_commitPending;
    9896    RefPtr<IDBTransactionCallbacks> m_callbacks;
    9997    RefPtr<IDBDatabaseBackendImpl> m_database;
     
    108106    // FIXME: delete the timer once we have threads instead.
    109107    Timer<IDBTransactionBackendImpl> m_taskTimer;
    110     Timer<IDBTransactionBackendImpl> m_taskEventTimer;
    111108    int m_pendingPreemptiveEvents;
    112     int m_pendingEvents;
    113109
    114110    HashSet<IDBCursorBackendImpl*> m_openCursors;
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransactionBackendInterface.h

    r134095 r135927  
    5555
    5656    virtual PassRefPtr<IDBObjectStoreBackendInterface> objectStore(int64_t, ExceptionCode&) = 0;
    57     virtual void didCompleteTaskEvents() = 0;
    5857    virtual void commit() = 0;
    5958    virtual void abort() = 0;
  • trunk/Source/WebKit/chromium/ChangeLog

    r135911 r135927  
     12012-11-27  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Simplify transaction timers and event tracking
     4        https://bugs.webkit.org/show_bug.cgi?id=102984
     5
     6        Reviewed by Tony Chang.
     7
     8        Remove now-unused didCompleteTaskEvents() method.
     9
     10        * src/IDBTransactionBackendProxy.cpp:
     11        * src/IDBTransactionBackendProxy.h:
     12        (IDBTransactionBackendProxy):
     13        * src/WebIDBTransactionImpl.cpp:
     14        * src/WebIDBTransactionImpl.h:
     15
    1162012-11-27  Alpha Lam  <hclam@chromium.org>
    217
  • trunk/Source/WebKit/chromium/src/IDBTransactionBackendProxy.cpp

    r134436 r135927  
    7373}
    7474
    75 void IDBTransactionBackendProxy::didCompleteTaskEvents()
    76 {
    77     m_webIDBTransaction->didCompleteTaskEvents();
    78 }
    79 
    8075void IDBTransactionBackendProxy::setCallbacks(IDBTransactionCallbacks* callbacks)
    8176{
  • trunk/Source/WebKit/chromium/src/IDBTransactionBackendProxy.h

    r134436 r135927  
    4545    virtual void commit();
    4646    virtual void abort();
    47     virtual void didCompleteTaskEvents();
    4847    virtual void setCallbacks(WebCore::IDBTransactionCallbacks*);
    4948
  • trunk/Source/WebKit/chromium/src/WebIDBTransactionImpl.cpp

    r134095 r135927  
    6666}
    6767
    68 void WebIDBTransactionImpl::didCompleteTaskEvents()
    69 {
    70     m_backend->didCompleteTaskEvents();
    71 }
    72 
    7368void WebIDBTransactionImpl::setCallbacks(WebIDBTransactionCallbacks* callbacks)
    7469{
  • trunk/Source/WebKit/chromium/src/WebIDBTransactionImpl.h

    r134095 r135927  
    4545    virtual void commit();
    4646    virtual void abort();
    47     virtual void didCompleteTaskEvents();
    4847    virtual void setCallbacks(WebIDBTransactionCallbacks*);
    4948
Note: See TracChangeset for help on using the changeset viewer.