⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 194263 in webkit


Ignore:
Timestamp:
Dec 17, 2015, 11:06:11 PM (11 years ago)
Author:
beidson@apple.com
Message:

Modern IDB: Refactor open/delete requests to exist in the same queue.
​https://bugs.webkit.org/show_bug.cgi?id=152397

Reviewed by Alex Christensen.

No new tests (Refactor, all existing tests continue to pass).

The order between incoming open and delete requests matters, and each request
needs to be handled individually.

This patch does the above without changing behavior on existing passing tests,
while moving many currently skipped tests closer to passing.

  • Modules/indexeddb/server/IDBServerOperation.cpp:

(WebCore::IDBServer::IDBServerOperation::notifyDeleteRequestBlocked):
(WebCore::IDBServer::IDBServerOperation::notifyDidDeleteDatabase):

  • Modules/indexeddb/server/IDBServerOperation.h:

(WebCore::IDBServer::IDBServerOperation::hasNotifiedDeleteRequestBlocked):

  • Modules/indexeddb/server/UniqueIDBDatabase.cpp:

(WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase):
(WebCore::IDBServer::UniqueIDBDatabase::openDatabaseConnection):
(WebCore::IDBServer::UniqueIDBDatabase::isVersionChangeInProgress):
(WebCore::IDBServer::UniqueIDBDatabase::performCurrentOpenOperation):
(WebCore::IDBServer::UniqueIDBDatabase::performCurrentDeleteOperation):
(WebCore::IDBServer::UniqueIDBDatabase::handleDatabaseOperations):
(WebCore::IDBServer::UniqueIDBDatabase::handleCurrentOperation):
(WebCore::IDBServer::UniqueIDBDatabase::handleDelete):
(WebCore::IDBServer::UniqueIDBDatabase::invokeOperationAndTransactionTimer):
(WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired):
(WebCore::IDBServer::UniqueIDBDatabase::maybeDeleteDatabase): Deleted.

  • Modules/indexeddb/server/UniqueIDBDatabase.h:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r194261 r194263  
     12015-12-17  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Refactor open/delete requests to exist in the same queue.
     4        https://bugs.webkit.org/show_bug.cgi?id=152397
     5
     6        Reviewed by Alex Christensen.
     7
     8        No new tests (Refactor, all existing tests continue to pass).
     9
     10        The order between incoming open and delete requests matters, and each request
     11        needs to be handled individually.
     12       
     13        This patch does the above without changing behavior on existing passing tests,
     14        while moving many currently skipped tests closer to passing.
     15   
     16        * Modules/indexeddb/server/IDBServerOperation.cpp:
     17        (WebCore::IDBServer::IDBServerOperation::notifyDeleteRequestBlocked):
     18        (WebCore::IDBServer::IDBServerOperation::notifyDidDeleteDatabase):
     19        * Modules/indexeddb/server/IDBServerOperation.h:
     20        (WebCore::IDBServer::IDBServerOperation::hasNotifiedDeleteRequestBlocked):
     21
     22        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
     23        (WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase):
     24        (WebCore::IDBServer::UniqueIDBDatabase::openDatabaseConnection):
     25        (WebCore::IDBServer::UniqueIDBDatabase::isVersionChangeInProgress):
     26        (WebCore::IDBServer::UniqueIDBDatabase::performCurrentOpenOperation):
     27        (WebCore::IDBServer::UniqueIDBDatabase::performCurrentDeleteOperation):
     28        (WebCore::IDBServer::UniqueIDBDatabase::handleDatabaseOperations):
     29        (WebCore::IDBServer::UniqueIDBDatabase::handleCurrentOperation):
     30        (WebCore::IDBServer::UniqueIDBDatabase::handleDelete):
     31        (WebCore::IDBServer::UniqueIDBDatabase::invokeOperationAndTransactionTimer):
     32        (WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired):
     33        (WebCore::IDBServer::UniqueIDBDatabase::maybeDeleteDatabase): Deleted.
     34        * Modules/indexeddb/server/UniqueIDBDatabase.h:
     35
    1362015-12-17  Csaba Osztrogonác  <ossy@webkit.org>
    237
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.cpp

    r194256 r194263  
    2929#if ENABLE(INDEXED_DATABASE)
    3030
     31#include "IDBResultData.h"
    3132#include <wtf/RefCounted.h>
    3233
    … …  
    5556}
    5657
     58void IDBServerOperation::notifyDeleteRequestBlocked(uint64_t currentVersion)
     59{
     60    ASSERT(isDeleteRequest());
     61    ASSERT(!m_notifiedDeleteRequestBlocked);
     62
     63    m_connection.notifyOpenDBRequestBlocked(m_requestData.requestIdentifier(), currentVersion, 0);
     64    m_notifiedDeleteRequestBlocked = true;
     65}
     66
     67void IDBServerOperation::notifyDidDeleteDatabase(const IDBDatabaseInfo& info)
     68{
     69    ASSERT(isDeleteRequest());
     70
     71    m_connection.didDeleteDatabase(IDBResultData::deleteDatabaseSuccess(m_requestData.requestIdentifier(), info));
     72}
     73
    5774} // namespace IDBServer
    5875} // namespace WebCore
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.h

    r194256 r194263  
    3535
    3636namespace WebCore {
     37
     38class IDBDatabaseInfo;
     39
    3740namespace IDBServer {
    3841
    … …  
    4750    bool isDeleteRequest() const;
    4851
     52    void notifyDeleteRequestBlocked(uint64_t currentVersion);
     53    void notifyDidDeleteDatabase(const IDBDatabaseInfo&);
     54    bool hasNotifiedDeleteRequestBlocked() const { return m_notifiedDeleteRequestBlocked; }
     55
    4956private:
    5057    IDBServerOperation(IDBConnectionToClient&, const IDBRequestData&);
    … …  
    5259    IDBConnectionToClient& m_connection;
    5360    IDBRequestData m_requestData;
     61
     62    bool m_notifiedDeleteRequestBlocked { false };
    5463};
    5564
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp

    r194256 r194263  
    5252}
    5353
     54UniqueIDBDatabase::~UniqueIDBDatabase()
     55{
     56    LOG(IndexedDB, "UniqueIDBDatabase::~UniqueIDBDatabase() (%p)", this);
     57    ASSERT(!hasAnyPendingCallbacks());
     58    ASSERT(m_inProgressTransactions.isEmpty());
     59    ASSERT(m_pendingTransactions.isEmpty());
     60    ASSERT(m_openDatabaseConnections.isEmpty());
     61}
     62
    5463const IDBDatabaseInfo& UniqueIDBDatabase::info() const
    5564{
    … …  
    6170{
    6271    auto operation = IDBServerOperation::create(connection, requestData);
    63     m_pendingOpenDatabaseOperations.append(WTF::move(operation));
    64 
    65     // An open operation is already in progress, so this one has to wait.
     72    m_pendingDatabaseOperations.append(WTF::move(operation));
     73
     74    // An open operation is already in progress, so we can't possibly handle this one yet.
    6675    if (m_isOpeningBackingStore)
    6776        return;
    … …  
    8493}
    8594
    86 bool UniqueIDBDatabase::maybeDeleteDatabase(IDBServerOperation* newestDeleteOperation)
    87 {
    88     ASSERT(isMainThread());
    89     LOG(IndexedDB, "(main) UniqueIDBDatabase::maybeDeleteDatabase");
    90 
    91     if (hasAnyOpenConnections() || !m_closePendingDatabaseConnections.isEmpty()) {
    92         // Exactly once, notify all open connections of the pending deletion.
    93         if (!m_hasNotifiedConnectionsOfDelete) {
    94             notifyConnectionsOfVersionChange(0);
    95             m_hasNotifiedConnectionsOfDelete = true;
    96         }
    97 
    98         if (newestDeleteOperation)
    99             newestDeleteOperation->connection().notifyOpenDBRequestBlocked(newestDeleteOperation->requestData().requestIdentifier(), m_databaseInfo->version(), 0);
    100 
    101         return false;
    102     }
    103 
    104     ASSERT(!hasAnyPendingCallbacks());
    105     ASSERT(m_inProgressTransactions.isEmpty());
    106     ASSERT(m_pendingTransactions.isEmpty());
    107     ASSERT(m_openDatabaseConnections.isEmpty());
    108     ASSERT(m_pendingOpenDatabaseOperations.isEmpty());
    109 
    110     for (auto& operation : m_pendingDeleteDatabaseOperations) {
    111         ASSERT(m_databaseInfo);
    112         ASSERT(operation->isDeleteRequest());
    113         operation->connection().didDeleteDatabase(IDBResultData::deleteDatabaseSuccess(operation->requestData().requestIdentifier(), *m_databaseInfo));
    114     }
    115 
    116     m_server.deleteUniqueIDBDatabase(*this);
    117 
    118     return true;
     95bool UniqueIDBDatabase::isVersionChangeInProgress()
     96{
     97#ifndef NDEBUG
     98    if (m_versionChangeTransaction)
     99        ASSERT(m_versionChangeDatabaseConnection);
     100#endif
     101
     102    return m_versionChangeDatabaseConnection;
    119103}
    120104
    … …  
    125109    ASSERT(m_currentOperation);
    126110    ASSERT(m_currentOperation->isOpenRequest());
     111
     112    // If we previously started a version change operation but were blocked by having open connections,
     113    // we might now be unblocked.
     114    if (m_versionChangeDatabaseConnection) {
     115        if (!m_versionChangeTransaction && !hasAnyOpenConnections())
     116            startVersionChangeTransaction();
     117        return;
     118    }
    127119
    128120    // 3.3.1 Opening a database
    … …  
    177169    LOG(IndexedDB, "(main) UniqueIDBDatabase::performCurrentDeleteOperation");
    178170
    179     // Not used yet.
     171    ASSERT(m_databaseInfo);
     172    ASSERT(m_currentOperation);
     173    ASSERT(m_currentOperation->isDeleteRequest());
     174
     175    if (hasAnyOpenConnections()) {
     176        // Exactly once, notify all open connections of the pending deletion.
     177        if (!m_hasNotifiedConnectionsOfDelete) {
     178            notifyConnectionsOfVersionChange(0);
     179            m_hasNotifiedConnectionsOfDelete = true;
     180        }
     181
     182        if (!m_currentOperation->hasNotifiedDeleteRequestBlocked())
     183            m_currentOperation->notifyDeleteRequestBlocked(m_databaseInfo->version());
     184
     185        return;
     186    }
     187
     188    ASSERT(!hasAnyPendingCallbacks());
     189    ASSERT(m_inProgressTransactions.isEmpty());
     190    ASSERT(m_pendingTransactions.isEmpty());
     191    ASSERT(m_openDatabaseConnections.isEmpty());
     192
     193    m_currentOperation->notifyDidDeleteDatabase(*m_databaseInfo);
     194    m_currentOperation = nullptr;
     195    m_hasNotifiedConnectionsOfDelete = false;
     196    m_deletePending = false;
     197
     198    if (m_pendingDatabaseOperations.isEmpty())
     199        m_server.deleteUniqueIDBDatabase(*this);
     200    else
     201        invokeOperationAndTransactionTimer();
    180202}
    181203
    … …  
    183205{
    184206    ASSERT(isMainThread());
    185     LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDatabaseOperations");
    186 
    187     // If a version change transaction is currently in progress, no new connections can be opened right now.
    188     // We will try again later.
    189     if (m_versionChangeDatabaseConnection)
     207    LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDatabaseOperations - There are %zu pending", m_pendingDatabaseOperations.size());
     208
     209    if (m_pendingDatabaseOperations.isEmpty())
    190210        return;
    191211
    192     if (m_pendingOpenDatabaseOperations.isEmpty())
    193         return;
    194 
    195     if (m_currentOperation)
    196         return;
    197 
    198     m_currentOperation = m_pendingOpenDatabaseOperations.takeFirst();
    199 
    200     // FIXME: Once handleDatabaseOperations also handles delete operations, remove this ASSERT.
    201     ASSERT(m_currentOperation->isOpenRequest());
     212    if (m_versionChangeDatabaseConnection || m_currentOperation) {
     213        // We can't start the next database operation quite yet, but we might need to notify all open connections
     214        // about a pending delete.
     215        if (m_pendingDatabaseOperations.first()->isDeleteRequest() && !m_hasNotifiedConnectionsOfDelete) {
     216            m_hasNotifiedConnectionsOfDelete = true;
     217            notifyConnectionsOfVersionChange(0);
     218        }
     219    }
     220
     221    m_currentOperation = m_pendingDatabaseOperations.takeFirst();
     222    LOG(IndexedDB, "UniqueIDBDatabase::handleDatabaseOperations - Popped an operation, now there are %zu pending", m_pendingDatabaseOperations.size());
     223
     224    handleCurrentOperation();
     225}
     226
     227void UniqueIDBDatabase::handleCurrentOperation()
     228{
     229    ASSERT(m_currentOperation);
     230
     231    RefPtr<UniqueIDBDatabase> protector(this);
    202232
    203233    if (m_currentOperation->isOpenRequest())
    … …  
    207237    else
    208238        ASSERT_NOT_REACHED();
     239
     240    if (!m_currentOperation)
     241        invokeOperationAndTransactionTimer();
    209242}
    210243
    … …  
    257290    LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDelete");
    258291
    259     auto operation = IDBServerOperation::create(connection, requestData);
    260     auto* rawOperation = &operation.get();
    261     m_pendingDeleteDatabaseOperations.append(WTF::move(operation));
    262 
    263     // If a different request has already come in to delete this database, there's nothing left to do.
    264     // A delete is already in progress, and this request will be handled along with all the rest.
    265     if (m_deletePending)
    266         return;
    267 
    268     m_deletePending = true;
    269 
    270     maybeDeleteDatabase(rawOperation);
     292    m_pendingDatabaseOperations.append(IDBServerOperation::create(connection, requestData));
     293    handleDatabaseOperations();
    271294}
    272295
    … …  
    938961void UniqueIDBDatabase::invokeOperationAndTransactionTimer()
    939962{
     963    LOG(IndexedDB, "UniqueIDBDatabase::invokeOperationAndTransactionTimer()");
    940964    if (!m_operationAndTransactionTimer.isActive())
    941965        m_operationAndTransactionTimer.startOneShot(0);
    … …  
    946970    LOG(IndexedDB, "(main) UniqueIDBDatabase::operationAndTransactionTimerFired");
    947971
    948     handleDatabaseOperations();
    949 
    950     if (m_deletePending && maybeDeleteDatabase(nullptr))
    951         return;
    952 
    953     // If the database was not deleted in the previous step, try to run a transaction now.
    954     if (m_pendingTransactions.isEmpty()) {
    955         if (!hasAnyOpenConnections() && m_currentOperation) {
    956             startVersionChangeTransaction();
    957             return;
    958         }
    959     }
     972    RefPtr<UniqueIDBDatabase> protector(this);
     973
     974    // The current operation might require multiple attempts to handle, so try to
     975    // make further progress on it now.
     976    if (m_currentOperation)
     977        handleCurrentOperation();
     978
     979    if (!m_currentOperation)
     980        handleDatabaseOperations();
    960981
    961982    bool hadDeferredTransactions = false;
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h

    r194256 r194263  
    7272    }
    7373
     74    ~UniqueIDBDatabase();
     75
    7476    void openDatabaseConnection(IDBConnectionToClient&, const IDBRequestData&);
    7577
    … …  
    106108   
    107109    void handleDatabaseOperations();
     110    void handleCurrentOperation();
    108111    void performCurrentOpenOperation();
    109112    void performCurrentDeleteOperation();
    110113    void addOpenDatabaseConnection(Ref<UniqueIDBDatabaseConnection>&&);
    111     bool maybeDeleteDatabase(IDBServerOperation*);
    112114    bool hasAnyOpenConnections() const;
    113115
    … …  
    115117    void notifyConnectionsOfVersionChangeForUpgrade();
    116118    void notifyConnectionsOfVersionChange(uint64_t requestedVersion);
     119    bool isVersionChangeInProgress();
    117120
    118121    void activateTransactionInBackingStore(UniqueIDBDatabaseTransaction&);
    … …  
    174177    IDBDatabaseIdentifier m_identifier;
    175178   
    176     Deque<Ref<IDBServerOperation>> m_pendingOpenDatabaseOperations;
    177     Deque<Ref<IDBServerOperation>> m_pendingDeleteDatabaseOperations;
     179    Deque<Ref<IDBServerOperation>> m_pendingDatabaseOperations;
    178180    RefPtr<IDBServerOperation> m_currentOperation;
    179181
Note: See TracChangeset for help on using the changeset viewer.