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

Changeset 194414 in webkit


Ignore:
Timestamp:
Dec 23, 2015, 11:40:29 PM (11 years ago)
Author:
beidson@apple.com
Message:

Modern IDB: Don't open any new connections until after version change transactions are completely handled.
https://bugs.webkit.org/show_bug.cgi?id=152441

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (At least 4 failing tests now pass).

When a version change transaction is in progress for a database, the server should not open any new connections
to that database until the version change transaction has been 100% completed.

This means *all* events related to finishing the transaction must fire.

To support this, a new message from client -> server is added.

  • Modules/indexeddb/client/IDBConnectionToServer.cpp:

(WebCore::IDBClient::IDBConnectionToServer::didFinishHandlingVersionChangeTransaction):

  • Modules/indexeddb/client/IDBConnectionToServer.h:
  • Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
  • Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp:

(WebCore::IDBClient::IDBOpenDBRequest::dispatchEvent):

  • Modules/indexeddb/client/IDBOpenDBRequestImpl.h:
  • Modules/indexeddb/client/IDBRequestImpl.h:
  • Modules/indexeddb/server/IDBServer.cpp:

(WebCore::IDBServer::IDBServer::didFinishHandlingVersionChangeTransaction):

  • Modules/indexeddb/server/IDBServer.h:
  • Modules/indexeddb/server/UniqueIDBDatabase.cpp:

(WebCore::IDBServer::UniqueIDBDatabase::handleDatabaseOperations):
(WebCore::IDBServer::UniqueIDBDatabase::didFinishHandlingVersionChange):
(WebCore::IDBServer::UniqueIDBDatabase::commitTransaction): Deleted.
(WebCore::IDBServer::UniqueIDBDatabase::didPerformAbortTransaction): Deleted.
(WebCore::IDBServer::UniqueIDBDatabase::inProgressTransactionCompleted): Deleted.

  • Modules/indexeddb/server/UniqueIDBDatabase.h:
  • Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:

(WebCore::IDBServer::UniqueIDBDatabaseTransaction::didFinishHandlingVersionChange):

  • Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:
  • Modules/indexeddb/shared/IDBTransactionInfo.cpp:

(WebCore::IDBTransactionInfo::loggingString):

  • Modules/indexeddb/shared/IDBTransactionInfo.h:
  • Modules/indexeddb/shared/InProcessIDBServer.cpp:

(WebCore::InProcessIDBServer::didFinishHandlingVersionChangeTransaction):

  • Modules/indexeddb/shared/InProcessIDBServer.h:

LayoutTests:

  • platform/mac-wk1/TestExpectations: Enable 4 now-passing tests.
Location:
trunk
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r194413 r194414  
     12015-12-23  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Don't open any new connections until after version change transactions are completely handled.
     4        https://bugs.webkit.org/show_bug.cgi?id=152441
     5
     6        Reviewed by Alex Christensen.
     7
     8        * platform/mac-wk1/TestExpectations: Enable 4 now-passing tests.
     9
    1102015-12-23  Brady Eidson  <beidson@apple.com>
    211
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r194413 r194414  
    100100storage/indexeddb/delete-closed-database-object.html [ Failure ]
    101101storage/indexeddb/intversion-gated-on-delete.html [ Failure ]
    102 storage/indexeddb/intversion-open-in-upgradeneeded.html [ Failure ]
    103 storage/indexeddb/intversion-pending-version-changes-descending.html [ Failure ]
    104 storage/indexeddb/intversion-pending-version-changes-same.html [ Failure ]
    105 storage/indexeddb/intversion-two-opens-no-versions.html [ Failure ]
    106102storage/indexeddb/odd-strings.html [ Failure ]
    107103storage/indexeddb/open-db-private-browsing.html [ Failure ]
  • trunk/Source/WebCore/ChangeLog

    r194413 r194414  
     12015-12-23  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Don't open any new connections until after version change transactions are completely handled.
     4        https://bugs.webkit.org/show_bug.cgi?id=152441
     5
     6        Reviewed by Alex Christensen.
     7
     8        No new tests (At least 4 failing tests now pass).
     9       
     10        When a version change transaction is in progress for a database, the server should not open any new connections
     11        to that database until the version change transaction has been 100% completed.
     12       
     13        This means *all* events related to finishing the transaction must fire.
     14       
     15        To support this, a new message from client -> server is added.
     16
     17        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
     18        (WebCore::IDBClient::IDBConnectionToServer::didFinishHandlingVersionChangeTransaction):
     19        * Modules/indexeddb/client/IDBConnectionToServer.h:
     20        * Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
     21       
     22        * Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp:
     23        (WebCore::IDBClient::IDBOpenDBRequest::dispatchEvent):
     24        * Modules/indexeddb/client/IDBOpenDBRequestImpl.h:
     25        * Modules/indexeddb/client/IDBRequestImpl.h:
     26       
     27        * Modules/indexeddb/server/IDBServer.cpp:
     28        (WebCore::IDBServer::IDBServer::didFinishHandlingVersionChangeTransaction):
     29        * Modules/indexeddb/server/IDBServer.h:
     30       
     31        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
     32        (WebCore::IDBServer::UniqueIDBDatabase::handleDatabaseOperations):
     33        (WebCore::IDBServer::UniqueIDBDatabase::didFinishHandlingVersionChange):
     34        (WebCore::IDBServer::UniqueIDBDatabase::commitTransaction): Deleted.
     35        (WebCore::IDBServer::UniqueIDBDatabase::didPerformAbortTransaction): Deleted.
     36        (WebCore::IDBServer::UniqueIDBDatabase::inProgressTransactionCompleted): Deleted.
     37        * Modules/indexeddb/server/UniqueIDBDatabase.h:
     38       
     39        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
     40        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::didFinishHandlingVersionChange):
     41        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:
     42       
     43        * Modules/indexeddb/shared/IDBTransactionInfo.cpp:
     44        (WebCore::IDBTransactionInfo::loggingString):
     45        * Modules/indexeddb/shared/IDBTransactionInfo.h:
     46       
     47        * Modules/indexeddb/shared/InProcessIDBServer.cpp:
     48        (WebCore::InProcessIDBServer::didFinishHandlingVersionChangeTransaction):
     49        * Modules/indexeddb/shared/InProcessIDBServer.h:
     50
    1512015-12-23  Brady Eidson  <beidson@apple.com>
    252
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp

    r193784 r194414  
    291291}
    292292
     293void IDBConnectionToServer::didFinishHandlingVersionChangeTransaction(IDBTransaction& transaction)
     294{
     295    LOG(IndexedDB, "IDBConnectionToServer::didFinishHandlingVersionChangeTransaction");
     296    auto identifier = transaction.info().identifier();
     297    m_delegate->didFinishHandlingVersionChangeTransaction(identifier);
     298}
     299
    293300void IDBConnectionToServer::abortTransaction(IDBTransaction& transaction)
    294301{
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h

    r193784 r194414  
    9999    void didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
    100100
     101    void didFinishHandlingVersionChangeTransaction(IDBTransaction&);
     102
    101103    void abortTransaction(IDBTransaction&);
    102104    void didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h

    r192645 r194414  
    6060    virtual void abortTransaction(IDBResourceIdentifier&) = 0;
    6161    virtual void commitTransaction(IDBResourceIdentifier&) = 0;
     62    virtual void didFinishHandlingVersionChangeTransaction(IDBResourceIdentifier&) = 0;
    6263    virtual void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&) = 0;
    6364    virtual void deleteObjectStore(const IDBRequestData&, const String& objectStoreName) = 0;
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp

    r194169 r194414  
    102102}
    103103
     104bool IDBOpenDBRequest::dispatchEvent(Event& event)
     105{
     106    bool result = IDBRequest::dispatchEvent(event);
     107
     108    if (m_transaction && m_transaction->isVersionChange() && (event.type() == eventNames().errorEvent || event.type() == eventNames().successEvent))
     109        m_transaction->database().serverConnection().didFinishHandlingVersionChangeTransaction(*m_transaction);
     110
     111    return result;
     112}
     113
    104114void IDBOpenDBRequest::onSuccess(const IDBResultData& resultData)
    105115{
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBOpenDBRequestImpl.h

    r194169 r194414  
    5858    void fireErrorAfterVersionChangeCompletion();
    5959
     60    virtual bool dispatchEvent(Event&) override final;
     61
    6062private:
    6163    IDBOpenDBRequest(IDBConnectionToServer&, ScriptExecutionContext*, const IDBDatabaseIdentifier&, uint64_t version, IndexedDB::RequestType);
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h

    r194169 r194414  
    8080
    8181    void enqueueEvent(Ref<Event>&&);
    82     virtual bool dispatchEvent(Event&) override final;
     82    virtual bool dispatchEvent(Event&) override;
    8383
    8484    IDBConnectionToServer& connection() { return m_connection; }
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp

    r192687 r194414  
    318318}
    319319
     320void IDBServer::didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier& transactionIdentifier)
     321{
     322    LOG(IndexedDB, "IDBServer::didFinishHandlingVersionChangeTransaction");
     323
     324    auto transaction = m_transactions.get(transactionIdentifier);
     325    if (!transaction)
     326        return;
     327
     328    transaction->didFinishHandlingVersionChange();
     329}
     330
    320331void IDBServer::databaseConnectionClosed(uint64_t databaseConnectionIdentifier)
    321332{
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h

    r192687 r194414  
    6161    void abortTransaction(const IDBResourceIdentifier&);
    6262    void commitTransaction(const IDBResourceIdentifier&);
     63    void didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier&);
    6364    void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&);
    6465    void deleteObjectStore(const IDBRequestData&, const String& objectStoreName);
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp

    r194275 r194414  
    207207    LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDatabaseOperations - There are %zu pending", m_pendingDatabaseOperations.size());
    208208
    209     if (m_versionChangeDatabaseConnection || m_currentOperation) {
    210         // We can't start the next database operation quite yet, but we might need to notify all open connections
    211         // about a pending delete.
    212         if (!m_pendingDatabaseOperations.isEmpty() && m_pendingDatabaseOperations.first()->isDeleteRequest() && !m_hasNotifiedConnectionsOfDelete) {
    213             m_hasNotifiedConnectionsOfDelete = true;
    214             notifyConnectionsOfVersionChange(0);
    215         }
     209    if (m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_currentOperation) {
     210        // We can't start any new open-database operations right now, but we might be able to start handling a delete operation.
     211        if (!m_currentOperation && !m_pendingDatabaseOperations.isEmpty() && m_pendingDatabaseOperations.first()->isDeleteRequest())
     212            m_currentOperation = m_pendingDatabaseOperations.takeFirst();
    216213
    217214        // Some operations (such as the first open operation after a delete) require multiple passes to completely handle
     
    850847        ASSERT(m_databaseInfo->version() == transaction.info().newVersion());
    851848
    852         m_versionChangeTransaction = nullptr;
    853         m_versionChangeDatabaseConnection = nullptr;
    854 
    855849        invokeOperationAndTransactionTimer();
    856850    }
     
    888882    uint64_t callbackID = storeCallback(callback);
    889883    m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performAbortTransaction, callbackID, transaction.info().identifier()));
     884}
     885
     886void UniqueIDBDatabase::didFinishHandlingVersionChange(UniqueIDBDatabaseTransaction& transaction)
     887{
     888    ASSERT(isMainThread());
     889    LOG(IndexedDB, "(main) UniqueIDBDatabase::didFinishHandlingVersionChange");
     890
     891    ASSERT(m_versionChangeTransaction);
     892    ASSERT_UNUSED(transaction, m_versionChangeTransaction == &transaction);
     893
     894    m_versionChangeTransaction = nullptr;
     895    m_versionChangeDatabaseConnection = nullptr;
     896
     897    invokeOperationAndTransactionTimer();
    890898}
    891899
     
    908916        ASSERT(m_versionChangeTransaction->originalDatabaseInfo());
    909917        m_databaseInfo = std::make_unique<IDBDatabaseInfo>(*m_versionChangeTransaction->originalDatabaseInfo());
    910 
    911         m_versionChangeTransaction = nullptr;
    912         m_versionChangeDatabaseConnection = nullptr;
    913918    }
    914919
     
    10951100    ASSERT(transaction);
    10961101
    1097     if (m_versionChangeTransaction == transaction)
    1098         m_versionChangeTransaction = nullptr;
    1099 
    11001102    for (auto objectStore : transaction->objectStoreIdentifiers())
    11011103        m_objectStoreTransactionCounts.remove(objectStore);
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h

    r194263 r194414  
    9393    void commitTransaction(UniqueIDBDatabaseTransaction&, ErrorCallback);
    9494    void abortTransaction(UniqueIDBDatabaseTransaction&, ErrorCallback);
     95    void didFinishHandlingVersionChange(UniqueIDBDatabaseTransaction&);
    9596    void transactionDestroyed(UniqueIDBDatabaseTransaction&);
    9697    void connectionClosedFromClient(UniqueIDBDatabaseConnection&);
     
    184185
    185186    RefPtr<UniqueIDBDatabaseConnection> m_versionChangeDatabaseConnection;
    186     UniqueIDBDatabaseTransaction* m_versionChangeTransaction { nullptr };
     187    RefPtr<UniqueIDBDatabaseTransaction> m_versionChangeTransaction;
    187188
    188189    bool m_isOpeningBackingStore { false };
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp

    r192645 r194414  
    310310}
    311311
     312void UniqueIDBDatabaseTransaction::didFinishHandlingVersionChange()
     313{
     314    LOG(IndexedDB, "UniqueIDBDatabaseTransaction::didFinishHandlingVersionChange");
     315    ASSERT(isVersionChange());
     316
     317    m_databaseConnection->database().didFinishHandlingVersionChange(*this);
     318}
     319
    312320} // namespace IDBServer
    313321} // namespace WebCore
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h

    r192645 r194414  
    8080
    8181    void didActivateInBackingStore(const IDBError&);
     82    void didFinishHandlingVersionChange();
    8283
    8384    const Vector<uint64_t>& objectStoreIdentifiers();
  • trunk/Source/WebCore/Modules/indexeddb/shared/IDBTransactionInfo.cpp

    r193643 r194414  
    2828
    2929#if ENABLE(INDEXED_DATABASE)
     30
     31#include "IDBTransactionImpl.h"
    3032
    3133namespace WebCore {
     
    8183}
    8284
     85#ifndef NDEBUG
     86String IDBTransactionInfo::loggingString() const
     87{
     88    String modeString;
     89    switch (m_mode) {
     90    case IndexedDB::TransactionMode::ReadOnly:
     91        modeString = IDBTransaction::modeReadOnly();
     92        break;
     93    case IndexedDB::TransactionMode::ReadWrite:
     94        modeString = IDBTransaction::modeReadWrite();
     95        break;
     96    case IndexedDB::TransactionMode::VersionChange:
     97        modeString = IDBTransaction::modeVersionChange();
     98        break;
     99    default:
     100        ASSERT_NOT_REACHED();
     101    }
     102   
     103    return makeString("Transaction: ", m_identifier.loggingString(), " mode ", modeString, " newVersion ", String::number(m_newVersion));
     104}
     105#endif
     106
    83107} // namespace WebCore
    84108
  • trunk/Source/WebCore/Modules/indexeddb/shared/IDBTransactionInfo.h

    r193643 r194414  
    6262    IDBDatabaseInfo* originalDatabaseInfo() const { return m_originalDatabaseInfo.get(); }
    6363
     64#ifndef NDEBUG
     65    String loggingString() const;
     66#endif
     67
    6468private:
    6569    IDBTransactionInfo(const IDBResourceIdentifier&);
  • trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp

    r193784 r194414  
    225225}
    226226
     227void InProcessIDBServer::didFinishHandlingVersionChangeTransaction(IDBResourceIdentifier& transactionIdentifier)
     228{
     229    RefPtr<InProcessIDBServer> self(this);
     230    RunLoop::current().dispatch([this, self, transactionIdentifier] {
     231        m_server->didFinishHandlingVersionChangeTransaction(transactionIdentifier);
     232    });
     233}
     234
    227235void InProcessIDBServer::createObjectStore(const IDBRequestData& resultData, const IDBObjectStoreInfo& info)
    228236{
  • trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h

    r193784 r194414  
    5959    virtual void abortTransaction(IDBResourceIdentifier&) override final;
    6060    virtual void commitTransaction(IDBResourceIdentifier&) override final;
     61    virtual void didFinishHandlingVersionChangeTransaction(IDBResourceIdentifier&) override final;
    6162    virtual void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&) override final;
    6263    virtual void deleteObjectStore(const IDBRequestData&, const String& objectStoreName) override final;
Note: See TracChangeset for help on using the changeset viewer.