REGRESSION (r250754): web page using IDBIndex doesn't load occasionally
authorsihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Nov 2019 18:25:38 +0000 (18:25 +0000)
committersihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Nov 2019 18:25:38 +0000 (18:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=203431

Reviewed by Brady Eidson.

Source/WebCore:

We now allow page to enter cache even when there are active IDB objects. The open database connection or blocked
database request on suspended pages may stop other active pages from deleting or opening the same database.

To fix this issue, we close those open connections on suspended page when we know from the versionchange event,
that there is open/delete request blocked. For blocked requests on suspended page, we abort them and return
error. This way, when the suspended page resumes, it will get close event fired on previously opened database
connections, and error event fired on previously blocked requests.

API test: IndexedDB.IndexedDBInPageCache

* Modules/indexeddb/IDBDatabase.h:
* Modules/indexeddb/IDBOpenDBRequest.cpp:
(WebCore::IDBOpenDBRequest::requestCompleted):
(WebCore::IDBOpenDBRequest::requestBlocked):
(WebCore::IDBOpenDBRequest::setIsContextSuspended):
* Modules/indexeddb/IDBOpenDBRequest.h:
* Modules/indexeddb/IndexedDB.h:
* Modules/indexeddb/client/IDBConnectionProxy.cpp:
(WebCore::IDBClient::IDBConnectionProxy::completeOpenDBRequest):
(WebCore::IDBClient::IDBConnectionProxy::fireVersionChangeEvent):
(WebCore::IDBClient::IDBConnectionProxy::didFireVersionChangeEvent):
(WebCore::IDBClient::setMatchingItemsContextSuspended):
(WebCore::IDBClient::IDBConnectionProxy::setContextSuspended):
* Modules/indexeddb/client/IDBConnectionProxy.h:
* Modules/indexeddb/client/IDBConnectionToServer.cpp:
(WebCore::IDBClient::IDBConnectionToServer::didFireVersionChangeEvent):
* Modules/indexeddb/client/IDBConnectionToServer.h:
* Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::didFireVersionChangeEvent):
* Modules/indexeddb/server/IDBServer.h:
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::clearTransactionsOnConnection):
(WebCore::IDBServer::UniqueIDBDatabase::didFireVersionChangeEvent):
(WebCore::IDBServer::UniqueIDBDatabase::connectionClosedFromClient):
* Modules/indexeddb/server/UniqueIDBDatabase.h:
* Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseConnection::didFireVersionChangeEvent):
* Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
* Modules/indexeddb/shared/InProcessIDBServer.cpp:
(WebCore::InProcessIDBServer::didFireVersionChangeEvent):
* Modules/indexeddb/shared/InProcessIDBServer.h:
* dom/Document.cpp:
(WebCore::Document::setBackForwardCacheState):
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::suspend):
(WebCore::WorkerGlobalScope::resume):
* workers/WorkerGlobalScope.h:
* workers/WorkerThread.cpp:
(WebCore::WorkerThread::suspend):

Source/WebKit:

* NetworkProcess/IndexedDB/WebIDBConnectionToClient.cpp:
(WebKit::WebIDBConnectionToClient::didFireVersionChangeEvent):
* NetworkProcess/IndexedDB/WebIDBConnectionToClient.h:
* NetworkProcess/IndexedDB/WebIDBConnectionToClient.messages.in:
* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
(WebKit::WebIDBConnectionToServer::didFireVersionChangeEvent):
* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.mm: Added.
(-[IndexedDBInPageCacheMessageHandler userContentController:didReceiveScriptMessage:]):
(TEST):
* TestWebKitAPI/Tests/WebKitCocoa/IndexedDBNotInPageCache.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252060 268f45cc-cd09-0410-ab3c-d52691b4dbfc

33 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBDatabase.h
Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.cpp
Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.h
Source/WebCore/Modules/indexeddb/IndexedDB.h
Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp
Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h
Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp
Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h
Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h
Source/WebCore/Modules/indexeddb/server/IDBServer.cpp
Source/WebCore/Modules/indexeddb/server/IDBServer.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h
Source/WebCore/dom/Document.cpp
Source/WebCore/workers/WorkerGlobalScope.cpp
Source/WebCore/workers/WorkerGlobalScope.h
Source/WebCore/workers/WorkerThread.cpp
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/IndexedDB/WebIDBConnectionToClient.cpp
Source/WebKit/NetworkProcess/IndexedDB/WebIDBConnectionToClient.h
Source/WebKit/NetworkProcess/IndexedDB/WebIDBConnectionToClient.messages.in
Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp
Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.mm [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBNotInPageCache.html [new file with mode: 0644]

index b452f4e..db8dc97 100644 (file)
@@ -1,3 +1,61 @@
+2019-11-05  Sihui Liu  <sihui_liu@apple.com>
+
+        REGRESSION (r250754): web page using IDBIndex doesn't load occasionally
+        https://bugs.webkit.org/show_bug.cgi?id=203431
+
+        Reviewed by Brady Eidson.
+
+        We now allow page to enter cache even when there are active IDB objects. The open database connection or blocked
+        database request on suspended pages may stop other active pages from deleting or opening the same database.
+
+        To fix this issue, we close those open connections on suspended page when we know from the versionchange event, 
+        that there is open/delete request blocked. For blocked requests on suspended page, we abort them and return 
+        error. This way, when the suspended page resumes, it will get close event fired on previously opened database 
+        connections, and error event fired on previously blocked requests.
+
+        API test: IndexedDB.IndexedDBInPageCache
+
+        * Modules/indexeddb/IDBDatabase.h:
+        * Modules/indexeddb/IDBOpenDBRequest.cpp:
+        (WebCore::IDBOpenDBRequest::requestCompleted):
+        (WebCore::IDBOpenDBRequest::requestBlocked):
+        (WebCore::IDBOpenDBRequest::setIsContextSuspended):
+        * Modules/indexeddb/IDBOpenDBRequest.h:
+        * Modules/indexeddb/IndexedDB.h:
+        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
+        (WebCore::IDBClient::IDBConnectionProxy::completeOpenDBRequest):
+        (WebCore::IDBClient::IDBConnectionProxy::fireVersionChangeEvent):
+        (WebCore::IDBClient::IDBConnectionProxy::didFireVersionChangeEvent):
+        (WebCore::IDBClient::setMatchingItemsContextSuspended):
+        (WebCore::IDBClient::IDBConnectionProxy::setContextSuspended):
+        * Modules/indexeddb/client/IDBConnectionProxy.h:
+        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
+        (WebCore::IDBClient::IDBConnectionToServer::didFireVersionChangeEvent):
+        * Modules/indexeddb/client/IDBConnectionToServer.h:
+        * Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::didFireVersionChangeEvent):
+        * Modules/indexeddb/server/IDBServer.h:
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::clearTransactionsOnConnection):
+        (WebCore::IDBServer::UniqueIDBDatabase::didFireVersionChangeEvent):
+        (WebCore::IDBServer::UniqueIDBDatabase::connectionClosedFromClient):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::didFireVersionChangeEvent):
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
+        * Modules/indexeddb/shared/InProcessIDBServer.cpp:
+        (WebCore::InProcessIDBServer::didFireVersionChangeEvent):
+        * Modules/indexeddb/shared/InProcessIDBServer.h:
+        * dom/Document.cpp:
+        (WebCore::Document::setBackForwardCacheState):
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::suspend):
+        (WebCore::WorkerGlobalScope::resume):
+        * workers/WorkerGlobalScope.h:
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThread::suspend):
+
 2019-11-05  Eric Carlson  <eric.carlson@apple.com>
 
         http/tests/media/track-in-band-hls-metadata.html sometimes crashes after r251626
index bfa0f4d..b45091b 100644 (file)
@@ -110,6 +110,9 @@ public:
 
     bool hasPendingActivity() const final;
 
+    void setIsContextSuspended(bool isContextSuspended) { m_isContextSuspended = isContextSuspended; }
+    bool isContextSuspended() const { return m_isContextSuspended; }
+
 private:
     IDBDatabase(ScriptExecutionContext&, IDBClient::IDBConnectionProxy&, const IDBResultData&);
 
@@ -130,6 +133,8 @@ private:
     HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_abortingTransactions;
     
     const EventNames& m_eventNames; // Need to cache this so we can use it from GC threads.
+
+    bool m_isContextSuspended { false };
 };
 
 } // namespace WebCore
index 9eae8d4..e588fae 100644 (file)
@@ -190,6 +190,8 @@ void IDBOpenDBRequest::requestCompleted(const IDBResultData& data)
 
     ASSERT(&originThread() == &Thread::current());
 
+    m_isBlocked = false;
+
     // If an Open request was completed after the page has navigated, leaving this request
     // with a stopped script execution context, we need to message back to the server so it
     // doesn't hang waiting on a database connection or transaction that will never exist.
@@ -229,11 +231,28 @@ void IDBOpenDBRequest::requestCompleted(const IDBResultData& data)
 void IDBOpenDBRequest::requestBlocked(uint64_t oldVersion, uint64_t newVersion)
 {
     ASSERT(&originThread() == &Thread::current());
+    ASSERT(!m_isBlocked);
+
+    m_isBlocked = true;
 
     LOG(IndexedDB, "IDBOpenDBRequest::requestBlocked");
     enqueueEvent(IDBVersionChangeEvent::create(oldVersion, newVersion, eventNames().blockedEvent));
 }
 
+void IDBOpenDBRequest::setIsContextSuspended(bool isContextSuspended)
+{
+    m_isContextSuspended = isContextSuspended;
+
+    // If this request is blocked, it means this request is being processed on the server.
+    // The client needs to actively stop the request so it doesn't blocks the processing of subsequent requests.
+    if (m_isBlocked) {
+        IDBRequestData requestData(connectionProxy(), *this);
+        connectionProxy().openDBRequestCancelled(requestData);
+        auto result = IDBResultData::error(requestData.requestIdentifier(), IDBError { UnknownError, "Blocked open request on cached page is aborted to unblock other requests"_s });
+        requestCompleted(result);
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
index 8748eb3..64a01bb 100644 (file)
@@ -52,6 +52,9 @@ public:
     void fireSuccessAfterVersionChangeCommit();
     void fireErrorAfterVersionChangeCompletion();
 
+    void setIsContextSuspended(bool);
+    bool isContextSuspended() const { return m_isContextSuspended; }
+
 private:
     IDBOpenDBRequest(ScriptExecutionContext&, IDBClient::IDBConnectionProxy&, const IDBDatabaseIdentifier&, uint64_t version, IndexedDB::RequestType);
 
@@ -68,6 +71,9 @@ private:
 
     IDBDatabaseIdentifier m_databaseIdentifier;
     uint64_t m_version { 0 };
+
+    bool m_isContextSuspended { false };
+    bool m_isBlocked { false };
 };
 
 } // namespace WebCore
index 6af93c4..509bbf2 100644 (file)
@@ -104,6 +104,8 @@ enum class GetAllType {
     Values,
 };
 
+enum class ConnectionClosedOnBehalfOfServer : bool { No, Yes };
+
 } // namespace IndexedDB
 
 } // namespace WebCore
index 497772d..c60e012 100644 (file)
@@ -115,6 +115,19 @@ void IDBConnectionProxy::completeOpenDBRequest(const IDBResultData& resultData)
     if (!request)
         return;
 
+    if (request->isContextSuspended()) {
+        switch (resultData.type()) {
+        case IDBResultType::OpenDatabaseUpgradeNeeded: {
+            abortOpenAndUpgradeNeeded(resultData.databaseConnectionIdentifier(), resultData.transactionInfo().identifier());
+            auto result = IDBResultData::error(resultData.requestIdentifier(), IDBError { UnknownError, "Version change transaction on cached page is aborted to unblock other connections"_s });
+            request->performCallbackOnOriginThread(*request, &IDBOpenDBRequest::requestCompleted, result);
+            return;
+        }
+        default:
+            break;
+        }
+    }
+
     request->performCallbackOnOriginThread(*request, &IDBOpenDBRequest::requestCompleted, resultData);
 }
 
@@ -268,12 +281,18 @@ void IDBConnectionProxy::fireVersionChangeEvent(uint64_t databaseConnectionIdent
     if (!database)
         return;
 
+    if (database->isContextSuspended()) {
+        didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer::Yes);
+        database->performCallbackOnOriginThread(*database, &IDBDatabase::connectionToServerLost, IDBError { UnknownError, "Connection on cached page closed to unblock other connections"_s});
+        return;
+    }
+
     database->performCallbackOnOriginThread(*database, &IDBDatabase::fireVersionChangeEvent, requestIdentifier, requestedVersion);
 }
 
-void IDBConnectionProxy::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
+void IDBConnectionProxy::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosed)
 {
-    callConnectionOnMainThread(&IDBConnectionToServer::didFireVersionChangeEvent, databaseConnectionIdentifier, requestIdentifier);
+    callConnectionOnMainThread(&IDBConnectionToServer::didFireVersionChangeEvent, databaseConnectionIdentifier, requestIdentifier, connectionClosed);
 }
 
 void IDBConnectionProxy::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
@@ -542,6 +561,23 @@ void removeItemsMatchingCurrentThread(HashMap<KeyType, ValueType>& map)
         map.remove(key);
 }
 
+template<typename KeyType, typename ValueType>
+void setMatchingItemsContextSuspended(ScriptExecutionContext& currentContext, HashMap<KeyType, ValueType>& map, bool isContextSuspended)
+{
+    auto& currentThread = Thread::current();
+    for (auto& iterator : map) {
+        if (&iterator.value->originThread() != &currentThread)
+            continue;
+
+        auto* context = iterator.value->scriptExecutionContext();
+        if (!context)
+            continue;
+
+        if (context == &currentContext)
+            iterator.value->setIsContextSuspended(isContextSuspended);
+    }
+}
+
 void IDBConnectionProxy::forgetActivityForCurrentThread()
 {
     ASSERT(!isMainThread());
@@ -566,6 +602,18 @@ void IDBConnectionProxy::forgetActivityForCurrentThread()
     }
 }
 
+void IDBConnectionProxy::setContextSuspended(ScriptExecutionContext& currentContext, bool isContextSuspended)
+{
+    {
+        Locker<Lock> lock(m_databaseConnectionMapLock);
+        setMatchingItemsContextSuspended(currentContext, m_databaseConnectionMap, isContextSuspended);
+    }
+    {
+        Locker<Lock> lock(m_openDBRequestMapLock);
+        setMatchingItemsContextSuspended(currentContext, m_openDBRequestMap, isContextSuspended);
+    }
+}
+
 } // namesapce IDBClient
 } // namespace WebCore
 
index 91f93c4..927c836 100644 (file)
@@ -85,7 +85,7 @@ public:
     void renameIndex(TransactionOperation&, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName);
 
     void fireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
-    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
+    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, const IndexedDB::ConnectionClosedOnBehalfOfServer = IndexedDB::ConnectionClosedOnBehalfOfServer::No);
 
     void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
     void openDBRequestCancelled(const IDBRequestData&);
@@ -124,6 +124,7 @@ public:
     void forgetActiveOperations(const Vector<RefPtr<TransactionOperation>>&);
     void forgetTransaction(IDBTransaction&);
     void forgetActivityForCurrentThread();
+    void setContextSuspended(ScriptExecutionContext& currentContext, bool isContextSuspended);
 
 private:
     void completeOpenDBRequest(const IDBResultData&);
index fc0d9b0..7570616 100644 (file)
@@ -415,13 +415,13 @@ void IDBConnectionToServer::fireVersionChangeEvent(uint64_t databaseConnectionId
     m_proxy->fireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, requestedVersion);
 }
 
-void IDBConnectionToServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
+void IDBConnectionToServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, const IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosed)
 {
     LOG(IndexedDB, "IDBConnectionToServer::didFireVersionChangeEvent");
     ASSERT(isMainThread());
 
     if (m_serverConnectionIsValid)
-        m_delegate->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier);
+        m_delegate->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, connectionClosed);
 }
 
 void IDBConnectionToServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
index 425e45a..8aae095 100644 (file)
@@ -116,7 +116,7 @@ public:
     WEBCORE_EXPORT void didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
 
     WEBCORE_EXPORT void fireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
-    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
+    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer);
 
     WEBCORE_EXPORT void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
 
index dc8a99b..9a8c12e 100644 (file)
@@ -48,6 +48,7 @@ struct SecurityOriginData;
 
 namespace IndexedDB {
 enum class ObjectStoreOverwriteMode;
+enum class ConnectionClosedOnBehalfOfServer : bool;
 }
 
 struct IDBKeyRangeData;
@@ -83,7 +84,7 @@ public:
     virtual void databaseConnectionPendingClose(uint64_t databaseConnectionIdentifier) = 0;
     virtual void databaseConnectionClosed(uint64_t databaseConnectionIdentifier) = 0;
     virtual void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier) = 0;
-    virtual void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier) = 0;
+    virtual void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, const IndexedDB::ConnectionClosedOnBehalfOfServer) = 0;
     virtual void openDBRequestCancelled(const IDBRequestData&) = 0;
     virtual void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier) = 0;
 
index a8e8567..e61db8c 100644 (file)
@@ -430,12 +430,12 @@ void IDBServer::abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier,
     databaseConnection->connectionClosedFromClient();
 }
 
-void IDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
+void IDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosed)
 {
     LOG(IndexedDB, "IDBServer::didFireVersionChangeEvent");
 
     if (auto databaseConnection = m_databaseConnections.get(databaseConnectionIdentifier))
-        databaseConnection->didFireVersionChangeEvent(requestIdentifier);
+        databaseConnection->didFireVersionChangeEvent(requestIdentifier, connectionClosed);
 }
 
 void IDBServer::openDBRequestCancelled(const IDBRequestData& requestData)
index 0755ed9..d3a223d 100644 (file)
@@ -90,7 +90,7 @@ public:
     WEBCORE_EXPORT void databaseConnectionPendingClose(uint64_t databaseConnectionIdentifier);
     WEBCORE_EXPORT void databaseConnectionClosed(uint64_t databaseConnectionIdentifier);
     WEBCORE_EXPORT void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier);
-    WEBCORE_EXPORT void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
+    WEBCORE_EXPORT void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer);
     WEBCORE_EXPORT void openDBRequestCancelled(const IDBRequestData&);
     WEBCORE_EXPORT void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
 
index 525ade9..fdeda63 100644 (file)
@@ -752,7 +752,29 @@ void UniqueIDBDatabase::notifyCurrentRequestConnectionClosedOrFiredVersionChange
     m_currentOpenDBRequest->maybeNotifyRequestBlocked(m_databaseInfo->version());
 }
 
-void UniqueIDBDatabase::didFireVersionChangeEvent(UniqueIDBDatabaseConnection& connection, const IDBResourceIdentifier& requestIdentifier)
+void UniqueIDBDatabase::clearTransactionsOnConnection(UniqueIDBDatabaseConnection& connection)
+{
+    Deque<RefPtr<UniqueIDBDatabaseTransaction>> pendingTransactions;
+    while (!m_pendingTransactions.isEmpty()) {
+        auto transaction = m_pendingTransactions.takeFirst();
+        if (&transaction->databaseConnection() != &connection)
+            pendingTransactions.append(WTFMove(transaction));
+        else
+            connection.deleteTransaction(*transaction);
+    }
+    if (!pendingTransactions.isEmpty())
+        m_pendingTransactions.swap(pendingTransactions);
+
+    Deque<RefPtr<UniqueIDBDatabaseTransaction>> transactionsToAbort;
+    for (auto& transaction : m_inProgressTransactions.values()) {
+        if (&transaction->databaseConnection() == &connection)
+            transactionsToAbort.append(transaction);
+    }
+    for (auto& transaction : transactionsToAbort)
+        transaction->abortWithoutCallback();
+}
+
+void UniqueIDBDatabase::didFireVersionChangeEvent(UniqueIDBDatabaseConnection& connection, const IDBResourceIdentifier& requestIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosedOnBehalfOfServer)
 {
     LOG(IndexedDB, "UniqueIDBDatabase::didFireVersionChangeEvent");
 
@@ -761,6 +783,13 @@ void UniqueIDBDatabase::didFireVersionChangeEvent(UniqueIDBDatabaseConnection& c
 
     ASSERT_UNUSED(requestIdentifier, m_currentOpenDBRequest->requestData().requestIdentifier() == requestIdentifier);
 
+    if (connectionClosedOnBehalfOfServer == IndexedDB::ConnectionClosedOnBehalfOfServer::Yes) {
+        if (m_openDatabaseConnections.contains(&connection)) {
+            clearTransactionsOnConnection(connection);
+            m_openDatabaseConnections.remove(&connection);
+        }
+    }
+
     notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent(connection.identifier());
 }
 
@@ -1845,24 +1874,7 @@ void UniqueIDBDatabase::connectionClosedFromClient(UniqueIDBDatabaseConnection&
         m_versionChangeDatabaseConnection = nullptr;
     }
 
-    Deque<RefPtr<UniqueIDBDatabaseTransaction>> pendingTransactions;
-    while (!m_pendingTransactions.isEmpty()) {
-        auto transaction = m_pendingTransactions.takeFirst();
-        if (&transaction->databaseConnection() != &connection)
-            pendingTransactions.append(WTFMove(transaction));
-    }
-
-    if (!pendingTransactions.isEmpty())
-        m_pendingTransactions.swap(pendingTransactions);
-
-    Deque<RefPtr<UniqueIDBDatabaseTransaction>> transactionsToAbort;
-    for (auto& transaction : m_inProgressTransactions.values()) {
-        if (&transaction->databaseConnection() == &connection)
-            transactionsToAbort.append(transaction);
-    }
-
-    for (auto& transaction : transactionsToAbort)
-        transaction->abortWithoutCallback();
+    clearTransactionsOnConnection(connection);
 
     if (m_currentOpenDBRequest)
         notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent(connection.identifier());
index cac2708..ec3fc0c 100644 (file)
@@ -105,7 +105,7 @@ public:
     void transactionDestroyed(UniqueIDBDatabaseTransaction&);
     void connectionClosedFromClient(UniqueIDBDatabaseConnection&);
     void confirmConnectionClosedOnServer(UniqueIDBDatabaseConnection&);
-    void didFireVersionChangeEvent(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier);
+    void didFireVersionChangeEvent(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer);
     void openDBRequestCancelled(const IDBResourceIdentifier& requestIdentifier);
     void confirmDidCloseFromServer(UniqueIDBDatabaseConnection&);
 
@@ -250,6 +250,8 @@ private:
     void startSpaceIncreaseTask(uint64_t identifier, uint64_t taskSize);
     void finishSpaceIncreaseTask(uint64_t identifier, bool isTaskSuccessful);
 
+    void clearTransactionsOnConnection(UniqueIDBDatabaseConnection&);
+
     static uint64_t generateUniqueCallbackIdentifier();
 
     Ref<IDBServer> m_server;
index 7fddf0f..fe910fa 100644 (file)
@@ -107,13 +107,13 @@ void UniqueIDBDatabaseConnection::confirmDidCloseFromServer()
         m_database->confirmDidCloseFromServer(*this);
 }
 
-void UniqueIDBDatabaseConnection::didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier)
+void UniqueIDBDatabaseConnection::didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosed)
 {
     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didFireVersionChangeEvent - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), identifier());
 
     ASSERT(m_database);
     if (m_database)
-        m_database->didFireVersionChangeEvent(*this, requestIdentifier);
+        m_database->didFireVersionChangeEvent(*this, requestIdentifier, connectionClosed);
 }
 
 void UniqueIDBDatabaseConnection::didFinishHandlingVersionChange(const IDBResourceIdentifier& transactionIdentifier)
index cca4f76..7f39864 100644 (file)
@@ -78,7 +78,7 @@ public:
     void didCreateIndex(const IDBResultData&);
     void didDeleteIndex(const IDBResultData&);
     void didRenameIndex(const IDBResultData&);
-    void didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier);
+    void didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer);
     void didFinishHandlingVersionChange(const IDBResourceIdentifier& transactionIdentifier);
     void confirmDidCloseFromServer();
 
index aa4823c..9111f59 100644 (file)
@@ -425,10 +425,10 @@ void InProcessIDBServer::abortOpenAndUpgradeNeeded(uint64_t databaseConnectionId
     });
 }
 
-void InProcessIDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
+void InProcessIDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, const IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosed)
 {
-    RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, requestIdentifier] {
-        m_server->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier);
+    RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, requestIdentifier, connectionClosed] {
+        m_server->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, connectionClosed);
     });
 }
 
index cadc812..c7b5321 100644 (file)
@@ -91,7 +91,7 @@ public:
     void databaseConnectionPendingClose(uint64_t databaseConnectionIdentifier) final;
     void databaseConnectionClosed(uint64_t databaseConnectionIdentifier) final;
     void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier) final;
-    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier) final;
+    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, const IndexedDB::ConnectionClosedOnBehalfOfServer = IndexedDB::ConnectionClosedOnBehalfOfServer::No) final;
     void openDBRequestCancelled(const IDBRequestData&) final;
     void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier) final;
     void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) final;
index 49eccb8..1e07c49 100644 (file)
@@ -5161,10 +5161,19 @@ void Document::setBackForwardCacheState(BackForwardCacheState state)
         m_styleRecalcTimer.stop();
 
         clearSharedObjectPool();
+
+#if ENABLE(INDEXED_DATABASE)
+        if (m_idbConnectionProxy)
+            m_idbConnectionProxy->setContextSuspended(*scriptExecutionContext(), true);
+#endif
         break;
     case NotInBackForwardCache:
         if (childNeedsStyleRecalc())
             scheduleStyleRecalc();
+#if ENABLE(INDEXED_DATABASE)
+        if (m_idbConnectionProxy)
+            m_idbConnectionProxy->setContextSuspended(*scriptExecutionContext(), false);
+#endif
         break;
     case AboutToEnterBackForwardCache:
         break;
index 58be506..aad96da 100644 (file)
@@ -210,6 +210,22 @@ void WorkerGlobalScope::stopIndexedDatabase()
 #endif
 }
 
+void WorkerGlobalScope::suspend()
+{
+#if ENABLE(INDEXED_DATABASE_IN_WORKERS)
+    if (m_connectionProxy)
+        m_connectionProxy->setContextSuspended(*scriptExecutionContext(), true);
+#endif
+}
+
+void WorkerGlobalScope::resume()
+{
+#if ENABLE(INDEXED_DATABASE_IN_WORKERS)
+    if (m_connectionProxy)
+        m_connectionProxy->setContextSuspended(*scriptExecutionContext(), false);
+#endif
+}
+
 #endif // ENABLE(INDEXED_DATABASE)
 
 WorkerLocation& WorkerGlobalScope::location() const
index 304471a..0d102ab 100644 (file)
@@ -75,6 +75,8 @@ public:
 
 #if ENABLE(INDEXED_DATABASE)
     IDBClient::IDBConnectionProxy* idbConnectionProxy() final;
+    void suspend();
+    void resume();
 #endif
 
     WorkerCacheStorageConnection& cacheStorageConnection();
index 275b5ee..f8e36de 100644 (file)
@@ -269,7 +269,13 @@ void WorkerThread::suspend()
 {
     m_isSuspended = true;
     runLoop().postTask([&](ScriptExecutionContext&) {
+        if (m_workerGlobalScope)
+            m_workerGlobalScope->suspend();
+
         m_suspensionSemaphore.wait();
+
+        if (m_workerGlobalScope)
+            m_workerGlobalScope->resume();
     });
 }
 
index 7404ea0..b23f436 100644 (file)
@@ -1,3 +1,18 @@
+2019-11-05  Sihui Liu  <sihui_liu@apple.com>
+
+        REGRESSION (r250754): web page using IDBIndex doesn't load occasionally
+        https://bugs.webkit.org/show_bug.cgi?id=203431
+
+        Reviewed by Brady Eidson.
+
+        * NetworkProcess/IndexedDB/WebIDBConnectionToClient.cpp:
+        (WebKit::WebIDBConnectionToClient::didFireVersionChangeEvent):
+        * NetworkProcess/IndexedDB/WebIDBConnectionToClient.h:
+        * NetworkProcess/IndexedDB/WebIDBConnectionToClient.messages.in:
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
+        (WebKit::WebIDBConnectionToServer::didFireVersionChangeEvent):
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h:
+
 2019-11-05  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         Unreviewed build fix for !ENABLE(MEDIA_STREAM) builds
index 0c812df..791c5df 100644 (file)
@@ -327,9 +327,9 @@ void WebIDBConnectionToClient::abortOpenAndUpgradeNeeded(uint64_t databaseConnec
     idbServer().abortOpenAndUpgradeNeeded(databaseConnectionIdentifier, transactionIdentifier);
 }
 
-void WebIDBConnectionToClient::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
+void WebIDBConnectionToClient::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier, IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosed)
 {
-    idbServer().didFireVersionChangeEvent(databaseConnectionIdentifier, transactionIdentifier);
+    idbServer().didFireVersionChangeEvent(databaseConnectionIdentifier, transactionIdentifier, connectionClosed);
 }
 
 void WebIDBConnectionToClient::openDBRequestCancelled(const IDBRequestData& requestData)
index de69632..6a6757d 100644 (file)
@@ -99,7 +99,7 @@ private:
     void databaseConnectionPendingClose(uint64_t databaseConnectionIdentifier);
     void databaseConnectionClosed(uint64_t databaseConnectionIdentifier);
     void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier);
-    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier);
+    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier, WebCore::IndexedDB::ConnectionClosedOnBehalfOfServer);
     void openDBRequestCancelled(const WebCore::IDBRequestData&);
     void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
 
index 803b96d..f60c208 100644 (file)
@@ -47,7 +47,7 @@ messages -> WebIDBConnectionToClient {
     DatabaseConnectionPendingClose(uint64_t databaseConnectionIdentifier);
     DatabaseConnectionClosed(uint64_t databaseConnectionIdentifier);
     AbortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier transactionIdentifier);
-    DidFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier requestIdentifier);
+    DidFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier requestIdentifier, WebCore::IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosedOnBehalfOfServer);
     OpenDBRequestCancelled(WebCore::IDBRequestData requestData);
     ConfirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
 
index 33eea24..8b5f1f1 100644 (file)
@@ -198,9 +198,9 @@ void WebIDBConnectionToServer::abortOpenAndUpgradeNeeded(uint64_t databaseConnec
     send(Messages::WebIDBConnectionToClient::AbortOpenAndUpgradeNeeded(databaseConnectionIdentifier, transactionIdentifier));
 }
 
-void WebIDBConnectionToServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
+void WebIDBConnectionToServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, const IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosed)
 {
-    send(Messages::WebIDBConnectionToClient::DidFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier));
+    send(Messages::WebIDBConnectionToClient::DidFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, connectionClosed));
 }
 
 void WebIDBConnectionToServer::openDBRequestCancelled(const IDBRequestData& requestData)
index b25259f..9570c40 100644 (file)
@@ -80,7 +80,7 @@ private:
     void databaseConnectionPendingClose(uint64_t databaseConnectionIdentifier) final;
     void databaseConnectionClosed(uint64_t databaseConnectionIdentifier) final;
     void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier) final;
-    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier) final;
+    void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier, const WebCore::IndexedDB::ConnectionClosedOnBehalfOfServer) final;
     void openDBRequestCancelled(const WebCore::IDBRequestData&) final;
     void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier) final;
 
index 2adc4a5..d6ff6d1 100644 (file)
@@ -1,3 +1,17 @@
+2019-11-05  Sihui Liu  <sihui_liu@apple.com>
+
+        REGRESSION (r250754): web page using IDBIndex doesn't load occasionally
+        https://bugs.webkit.org/show_bug.cgi?id=203431
+
+        Reviewed by Brady Eidson.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.mm: Added.
+        (-[IndexedDBInPageCacheMessageHandler userContentController:didReceiveScriptMessage:]):
+        (TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/IndexedDBNotInPageCache.html: Added.
+
 2019-11-05  Jonathan Bedard  <jbedard@apple.com>
 
         webkitpy: Build ImageDiff if it is missing (Follow-fix)
index 553fc91..61ce29f 100644 (file)
                9368A25F229EFB4700A829CA /* local-storage-process-suspends-2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9368A25C229EFB3A00A829CA /* local-storage-process-suspends-2.html */; };
                936F72801CD7D9EC0068A0FB /* large-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 936F727E1CD7D9D00068A0FB /* large-video-with-audio.html */; };
                936F72811CD7D9EC0068A0FB /* large-video-with-audio.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 936F727F1CD7D9D00068A0FB /* large-video-with-audio.mp4 */; };
+               9399BA0423711140008392BF /* IndexedDBInPageCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9399BA01237110AE008392BF /* IndexedDBInPageCache.mm */; };
+               9399BA052371114F008392BF /* IndexedDBInPageCache.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9399BA02237110BF008392BF /* IndexedDBInPageCache.html */; };
+               9399BA062371114F008392BF /* IndexedDBNotInPageCache.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9399BA03237110BF008392BF /* IndexedDBNotInPageCache.html */; };
                93AF4ECE1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */; };
                93AF4ED11506F130007FD57E /* lots-of-images.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93AF4ECF1506F123007FD57E /* lots-of-images.html */; };
                93B62054234EA62C00D49B97 /* StorageQuotaManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B62053234EA32B00D49B97 /* StorageQuotaManager.cpp */; };
                                51A587851D2739E3004BA9AF /* IndexedDBDatabaseProcessKill-1.html in Copy Resources */,
                                CAB0FF5222332407006CA5B0 /* IndexedDBFileName-1.html in Copy Resources */,
                                CAB0FF5322332407006CA5B0 /* IndexedDBFileName-2.html in Copy Resources */,
+                               9399BA052371114F008392BF /* IndexedDBInPageCache.html in Copy Resources */,
                                51BCEE4E1C84F53B0042C82E /* IndexedDBMultiProcess-1.html in Copy Resources */,
                                51BCEE4F1C84F53B0042C82E /* IndexedDBMultiProcess-2.html in Copy Resources */,
                                51A5877D1D1B49CD004BA9AF /* IndexedDBMultiProcess-3.html in Copy Resources */,
+                               9399BA062371114F008392BF /* IndexedDBNotInPageCache.html in Copy Resources */,
                                51B1EE961C80FAEF0064FB98 /* IndexedDBPersistence-1.html in Copy Resources */,
                                51B1EE971C80FAEF0064FB98 /* IndexedDBPersistence-2.html in Copy Resources */,
                                57599E271F071AA000A3FB8C /* IndexedDBStructuredCloneBackwardCompatibility.sqlite3 in Copy Resources */,
                9368A25D229EFB3A00A829CA /* local-storage-process-suspends-1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "local-storage-process-suspends-1.html"; sourceTree = "<group>"; };
                936F727E1CD7D9D00068A0FB /* large-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-with-audio.html"; sourceTree = "<group>"; };
                936F727F1CD7D9D00068A0FB /* large-video-with-audio.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "large-video-with-audio.mp4"; sourceTree = "<group>"; };
+               9399BA01237110AE008392BF /* IndexedDBInPageCache.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IndexedDBInPageCache.mm; sourceTree = "<group>"; };
+               9399BA02237110BF008392BF /* IndexedDBInPageCache.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IndexedDBInPageCache.html; sourceTree = "<group>"; };
+               9399BA03237110BF008392BF /* IndexedDBNotInPageCache.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IndexedDBNotInPageCache.html; sourceTree = "<group>"; };
                939BA91614103412001A01BD /* DeviceScaleFactorOnBack.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DeviceScaleFactorOnBack.mm; sourceTree = "<group>"; };
                939BFE3918E5548900883275 /* StringTruncator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringTruncator.mm; sourceTree = "<group>"; };
                93A258981F92FF15003E510C /* TextCodec.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TextCodec.cpp; sourceTree = "<group>"; };
                                5110FCEF1E01CBAA006F8D0B /* IDBIndexUpgradeToV2.mm */,
                                51A587841D272EF3004BA9AF /* IndexedDBDatabaseProcessKill.mm */,
                                CAB0FF5422332C3A006CA5B0 /* IndexedDBFileName.mm */,
+                               9399BA01237110AE008392BF /* IndexedDBInPageCache.mm */,
                                51BCEE491C84F4AF0042C82E /* IndexedDBMultiProcess.mm */,
                                51B1EE8D1C80F5880064FB98 /* IndexedDBPersistence.mm */,
                                57599E201F07191700A3FB8C /* IndexedDBStructuredCloneBackwardCompatibility.mm */,
                                51A587821D272EB5004BA9AF /* IndexedDBDatabaseProcessKill-1.html */,
                                CAB0FF51223323F6006CA5B0 /* IndexedDBFileName-1.html */,
                                CAB0FF50223323F6006CA5B0 /* IndexedDBFileName-2.html */,
+                               9399BA02237110BF008392BF /* IndexedDBInPageCache.html */,
                                51BCEE4C1C84F52C0042C82E /* IndexedDBMultiProcess-1.html */,
                                51BCEE4D1C84F52C0042C82E /* IndexedDBMultiProcess-2.html */,
                                51A5877C1D1B3D8D004BA9AF /* IndexedDBMultiProcess-3.html */,
+                               9399BA03237110BF008392BF /* IndexedDBNotInPageCache.html */,
                                51B1EE941C80FADD0064FB98 /* IndexedDBPersistence-1.html */,
                                51B1EE951C80FADD0064FB98 /* IndexedDBPersistence-2.html */,
                                57599E241F07192C00A3FB8C /* IndexedDBStructuredCloneBackwardCompatibility.sqlite3 */,
                                5110FCFA1E01CDB8006F8D0B /* IDBIndexUpgradeToV2.mm in Sources */,
                                51A587861D273AA9004BA9AF /* IndexedDBDatabaseProcessKill.mm in Sources */,
                                CAB0FF5522332C57006CA5B0 /* IndexedDBFileName.mm in Sources */,
+                               9399BA0423711140008392BF /* IndexedDBInPageCache.mm in Sources */,
                                7C83E0BE1D0A651300FEBCF3 /* IndexedDBMultiProcess.mm in Sources */,
                                7C83E0BF1D0A652200FEBCF3 /* IndexedDBPersistence.mm in Sources */,
                                57599E211F07191900A3FB8C /* IndexedDBStructuredCloneBackwardCompatibility.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.html
new file mode 100644 (file)
index 0000000..9378257
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<script>
+
+var db;
+var openErrorFired = false;
+var request = window.indexedDB.open("TestIndexedDB");
+request.onsuccess = (event) => {
+    db = event.target.result;
+    db.onclose = (event) => {
+        if (openErrorFired) {
+            var thirdOpenRequest = window.indexedDB.open("TestIndexedDB");
+            thirdOpenRequest.onsuccess = (event) => {
+                window.webkit.messageHandlers.testHandler.postMessage("First Database Connection Closed, Second Database Connection Not Failed, Third Database Connection Opened");
+            }
+            thirdOpenRequest.onblock = (event) => {
+                window.webkit.messageHandlers.testHandler.postMessage("Third Database Connection Blocked");
+            }
+            thirdOpenRequest.onerror = (event) => {
+                window.webkit.messageHandlers.testHandler.postMessage("Third Database Connection Failed");
+            }
+        } else {
+            window.webkit.messageHandlers.testHandler.postMessage("Second Database Connection Not Failed");
+        }
+    }
+
+    var secondOpenRequest = window.indexedDB.open("TestIndexedDB", db.version + 1);
+    secondOpenRequest.onerror = (event) => {
+        openErrorFired = true;
+    }
+
+    window.webkit.messageHandlers.testHandler.postMessage("First Database Connection Opened");
+}
+request.onerror = (event) => {
+    window.webkit.messageHandlers.testHandler.postMessage("First Database Connection Failed");
+}
+
+</script>
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBInPageCache.mm
new file mode 100644 (file)
index 0000000..64a9838
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#import "PlatformUtilities.h"
+#import "Test.h"
+
+#import <WebKit/WKProcessPoolPrivate.h>
+#import <WebKit/WKUserContentControllerPrivate.h>
+#import <WebKit/WKWebViewConfigurationPrivate.h>
+#import <WebKit/WKWebsiteDataStorePrivate.h>
+#import <WebKit/WebKit.h>
+#import <WebKit/_WKProcessPoolConfiguration.h>
+#import <WebKit/_WKUserStyleSheet.h>
+#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
+#import <wtf/RetainPtr.h>
+
+static bool receivedScriptMessage;
+static RetainPtr<WKScriptMessage> lastScriptMessage;
+
+@interface IndexedDBInPageCacheMessageHandler : NSObject <WKScriptMessageHandler>
+@end
+
+@implementation IndexedDBInPageCacheMessageHandler
+
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    receivedScriptMessage = true;
+    lastScriptMessage = message;
+}
+
+@end
+
+TEST(IndexedDB, IndexedDBInPageCache)
+{
+    auto handler = adoptNS([[IndexedDBInPageCacheMessageHandler alloc] init]);
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    // Load page that holds open database connection.
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"IndexedDBInPageCache" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request];
+
+    receivedScriptMessage = false;
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    RetainPtr<NSString> string1 = (NSString *)[lastScriptMessage body];
+    EXPECT_WK_STREQ(@"First Database Connection Opened", string1.get());
+
+    // Load another page that deletes database.
+    NSURLRequest *request2 = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"IndexedDBNotInPageCache" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request2];
+
+    receivedScriptMessage = false;
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    RetainPtr<NSString> string2 = (NSString *)[lastScriptMessage body];
+    EXPECT_WK_STREQ(@"Database Deleted", string2.get());
+
+    [webView goBack];
+    receivedScriptMessage = false;
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    RetainPtr<NSString> string3 = (NSString *)[lastScriptMessage body];
+    EXPECT_WK_STREQ(@"First Database Connection Closed, Second Database Connection Not Failed, Third Database Connection Opened", string3.get());
+}
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBNotInPageCache.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBNotInPageCache.html
new file mode 100644 (file)
index 0000000..56aecd8
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script>
+
+var request = window.indexedDB.deleteDatabase("TestIndexedDB");
+request.onsuccess = function(event) {
+    window.webkit.messageHandlers.testHandler.postMessage("Database Deleted");
+}
+request.onblocked = function(event) {
+    window.webkit.messageHandlers.testHandler.postMessage("Database Deletion Blocked");
+}
+
+</script>