Modern IDB: IDBOpenDBRequests that are stop()'ed don't notify the IDBServer of that...
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 May 2016 18:42:03 +0000 (18:42 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 May 2016 18:42:03 +0000 (18:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157448

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (Previously skipped tests cover new behavior, and are now unskipped).

There's two main parts to this patch:

1 - When an IDBOpenDBRequest is stop()'ed due to page navigation or worker termination,
    we now notify the IDBServer of that.
2 - Lot's of little tweaks to UniqueIDBDatabase to handle shutting down version change
    transactions and/or connections related to the cancelled openDB request.

Fortunately the changes to UniqueIDBDatabase were all well covered by existing tests.

* Modules/indexeddb/IDBOpenDBRequest.cpp:
(WebCore::IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit):
(WebCore::IDBOpenDBRequest::fireErrorAfterVersionChangeCompletion):
(WebCore::IDBOpenDBRequest::cancelForStop):
(WebCore::IDBOpenDBRequest::dispatchEvent):
* Modules/indexeddb/IDBOpenDBRequest.h:

* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::stop):
(WebCore::IDBRequest::cancelForStop):
* Modules/indexeddb/IDBRequest.h:

* Modules/indexeddb/client/IDBConnectionProxy.cpp:
(WebCore::IDBClient::IDBConnectionProxy::openDBRequestCancelled):
(WebCore::IDBClient::IDBConnectionProxy::didFinishHandlingVersionChangeTransaction):
* Modules/indexeddb/client/IDBConnectionProxy.h:

* Modules/indexeddb/client/IDBConnectionToServer.cpp:
(WebCore::IDBClient::IDBConnectionToServer::didFinishHandlingVersionChangeTransaction):
(WebCore::IDBClient::IDBConnectionToServer::openDBRequestCancelled):
* Modules/indexeddb/client/IDBConnectionToServer.h:

* Modules/indexeddb/client/IDBConnectionToServerDelegate.h:

* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::didFinishHandlingVersionChangeTransaction):
(WebCore::IDBServer::IDBServer::databaseConnectionClosed):
(WebCore::IDBServer::IDBServer::openDBRequestCancelled):
* Modules/indexeddb/server/IDBServer.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::handleCurrentOperation):
(WebCore::IDBServer::UniqueIDBDatabase::openDBRequestCancelled):
(WebCore::IDBServer::UniqueIDBDatabase::commitTransaction):
(WebCore::IDBServer::UniqueIDBDatabase::performCommitTransaction):
(WebCore::IDBServer::UniqueIDBDatabase::didPerformCommitTransaction):
(WebCore::IDBServer::UniqueIDBDatabase::abortTransaction):
(WebCore::IDBServer::UniqueIDBDatabase::didFinishHandlingVersionChange):
(WebCore::IDBServer::UniqueIDBDatabase::performAbortTransaction):
(WebCore::IDBServer::UniqueIDBDatabase::didPerformAbortTransaction):
(WebCore::IDBServer::UniqueIDBDatabase::connectionClosedFromClient):
(WebCore::IDBServer::UniqueIDBDatabase::transactionCompleted):
(WebCore::IDBServer::UniqueIDBDatabase::forgetErrorCallback):
* Modules/indexeddb/server/UniqueIDBDatabase.h:

* Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseConnection::abortTransactionWithoutCallback):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::didFinishHandlingVersionChange):
* Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:

* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::didFinishHandlingVersionChange): Deleted.
* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:

* Modules/indexeddb/shared/InProcessIDBServer.cpp:
(WebCore::InProcessIDBServer::didFinishHandlingVersionChangeTransaction):
(WebCore::InProcessIDBServer::openDBRequestCancelled):
* Modules/indexeddb/shared/InProcessIDBServer.h:

Source/WebKit2:

* DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp:
(WebKit::WebIDBConnectionToClient::didFinishHandlingVersionChangeTransaction):
(WebKit::WebIDBConnectionToClient::openDBRequestCancelled):
* DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h:
* DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in:

* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
(WebKit::WebIDBConnectionToServer::didFinishHandlingVersionChangeTransaction):
(WebKit::WebIDBConnectionToServer::openDBRequestCancelled):
* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h:

LayoutTests:

* TestExpectations:
* storage/indexeddb/pending-version-change-stuck-private-expected.txt:
* storage/indexeddb/pending-version-change-stuck-works-with-terminate-expected.txt:
* storage/indexeddb/pending-version-change-stuck-works-with-terminate-private-expected.txt:

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

31 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/storage/indexeddb/pending-version-change-stuck-private-expected.txt
LayoutTests/storage/indexeddb/pending-version-change-stuck-works-with-terminate-expected.txt
LayoutTests/storage/indexeddb/pending-version-change-stuck-works-with-terminate-private-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.cpp
Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.h
Source/WebCore/Modules/indexeddb/IDBRequest.cpp
Source/WebCore/Modules/indexeddb/IDBRequest.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/server/UniqueIDBDatabaseTransaction.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h
Source/WebKit2/ChangeLog
Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h
Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h

index 380f5f5..3299684 100644 (file)
@@ -1,3 +1,15 @@
+2016-05-11  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: IDBOpenDBRequests that are stop()'ed don't notify the IDBServer of that fact.
+        https://bugs.webkit.org/show_bug.cgi?id=157448
+
+        Reviewed by Alex Christensen.
+
+        * TestExpectations:
+        * storage/indexeddb/pending-version-change-stuck-private-expected.txt:
+        * storage/indexeddb/pending-version-change-stuck-works-with-terminate-expected.txt:
+        * storage/indexeddb/pending-version-change-stuck-works-with-terminate-private-expected.txt:
+
 2016-05-11  Joseph Pecoraro  <pecoraro@apple.com>
 
         Improve error messages for accessing arguments.callee and similar getters in strict mode
index a52d195..0062a42 100644 (file)
@@ -913,12 +913,6 @@ webkit.org/b/154619 storage/indexeddb/odd-strings.html [ Skip ]
 # Could be a SessionID difference? Something is giving the worker a different namespace.
 storage/indexeddb/dont-commit-on-blocked-private.html [ Failure ]
 
-# IDB workers tests that timeout
-storage/indexeddb/pending-version-change-stuck.html
-storage/indexeddb/pending-version-change-stuck-private.html
-storage/indexeddb/pending-version-change-stuck-works-with-terminate.html
-storage/indexeddb/pending-version-change-stuck-works-with-terminate-private.html
-
 # Test's behavior specific to Legacy IDB with LevelDB backend
 # Modern IDB is spec-compliant without supporting this behavior
 storage/indexeddb/transaction-starvation.html [ Skip ]
index 1134ddb..daa7c4d 100644 (file)
@@ -5,7 +5,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
 
-request = indexedDB.open("pending-version-change-stuck.html")
+request = indexedDB.open("pending-version-change-stuck-private.html")
 PASS Open worked after page reload.
 PASS successfullyParsed is true
 
index b895bfc..f5d17c4 100644 (file)
@@ -5,7 +5,6 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
 
-dbname = "pending-version-change-stuck-works-with-terminate.html"
 indexedDB.open(dbname)
 PASS Open worked after page reload.
 PASS successfullyParsed is true
index b895bfc..f5d17c4 100644 (file)
@@ -5,7 +5,6 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
 
-dbname = "pending-version-change-stuck-works-with-terminate.html"
 indexedDB.open(dbname)
 PASS Open worked after page reload.
 PASS successfullyParsed is true
index 5b3a4b7..2639657 100644 (file)
@@ -1,3 +1,81 @@
+2016-05-11  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: IDBOpenDBRequests that are stop()'ed don't notify the IDBServer of that fact.
+        https://bugs.webkit.org/show_bug.cgi?id=157448
+
+        Reviewed by Alex Christensen.
+
+        No new tests (Previously skipped tests cover new behavior, and are now unskipped).
+
+        There's two main parts to this patch:
+        
+        1 - When an IDBOpenDBRequest is stop()'ed due to page navigation or worker termination,
+            we now notify the IDBServer of that.
+        2 - Lot's of little tweaks to UniqueIDBDatabase to handle shutting down version change
+            transactions and/or connections related to the cancelled openDB request.
+            
+        Fortunately the changes to UniqueIDBDatabase were all well covered by existing tests.
+        
+        * Modules/indexeddb/IDBOpenDBRequest.cpp:
+        (WebCore::IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit):
+        (WebCore::IDBOpenDBRequest::fireErrorAfterVersionChangeCompletion):
+        (WebCore::IDBOpenDBRequest::cancelForStop):
+        (WebCore::IDBOpenDBRequest::dispatchEvent):
+        * Modules/indexeddb/IDBOpenDBRequest.h:
+
+        * Modules/indexeddb/IDBRequest.cpp:
+        (WebCore::IDBRequest::stop):
+        (WebCore::IDBRequest::cancelForStop):
+        * Modules/indexeddb/IDBRequest.h:
+
+        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
+        (WebCore::IDBClient::IDBConnectionProxy::openDBRequestCancelled):
+        (WebCore::IDBClient::IDBConnectionProxy::didFinishHandlingVersionChangeTransaction):
+        * Modules/indexeddb/client/IDBConnectionProxy.h:
+
+        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
+        (WebCore::IDBClient::IDBConnectionToServer::didFinishHandlingVersionChangeTransaction):
+        (WebCore::IDBClient::IDBConnectionToServer::openDBRequestCancelled):
+        * Modules/indexeddb/client/IDBConnectionToServer.h:
+
+        * Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
+
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::didFinishHandlingVersionChangeTransaction):
+        (WebCore::IDBServer::IDBServer::databaseConnectionClosed):
+        (WebCore::IDBServer::IDBServer::openDBRequestCancelled):
+        * Modules/indexeddb/server/IDBServer.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::handleCurrentOperation):
+        (WebCore::IDBServer::UniqueIDBDatabase::openDBRequestCancelled):
+        (WebCore::IDBServer::UniqueIDBDatabase::commitTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabase::performCommitTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabase::didPerformCommitTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabase::abortTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabase::didFinishHandlingVersionChange):
+        (WebCore::IDBServer::UniqueIDBDatabase::performAbortTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabase::didPerformAbortTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabase::connectionClosedFromClient):
+        (WebCore::IDBServer::UniqueIDBDatabase::transactionCompleted):
+        (WebCore::IDBServer::UniqueIDBDatabase::forgetErrorCallback):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::abortTransactionWithoutCallback):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::didFinishHandlingVersionChange):
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::didFinishHandlingVersionChange): Deleted.
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:
+
+        * Modules/indexeddb/shared/InProcessIDBServer.cpp:
+        (WebCore::InProcessIDBServer::didFinishHandlingVersionChangeTransaction):
+        (WebCore::InProcessIDBServer::openDBRequestCancelled):
+        * Modules/indexeddb/shared/InProcessIDBServer.h:
+
 2016-05-11  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed, rolling out r200686.
index bb8889d..8a1e057 100644 (file)
@@ -84,7 +84,7 @@ void IDBOpenDBRequest::versionChangeTransactionDidFinish()
 
 void IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit()
 {
-    LOG(IndexedDB, "IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit()");
+    LOG(IndexedDB, "IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit() - %s", resourceIdentifier().loggingString().utf8().data());
 
     ASSERT(currentThread() == originThreadID());
     ASSERT(hasPendingActivity());
@@ -98,7 +98,7 @@ void IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit()
 
 void IDBOpenDBRequest::fireErrorAfterVersionChangeCompletion()
 {
-    LOG(IndexedDB, "IDBOpenDBRequest::fireErrorAfterVersionChangeCompletion()");
+    LOG(IndexedDB, "IDBOpenDBRequest::fireErrorAfterVersionChangeCompletion() - %s", resourceIdentifier().loggingString().utf8().data());
 
     ASSERT(currentThread() == originThreadID());
     ASSERT(hasPendingActivity());
@@ -111,6 +111,11 @@ void IDBOpenDBRequest::fireErrorAfterVersionChangeCompletion()
     enqueueEvent(IDBRequestCompletionEvent::create(eventNames().errorEvent, true, true, *this));
 }
 
+void IDBOpenDBRequest::cancelForStop()
+{
+    connectionProxy().openDBRequestCancelled({ connectionProxy(), *this });
+}
+
 bool IDBOpenDBRequest::dispatchEvent(Event& event)
 {
     ASSERT(currentThread() == originThreadID());
@@ -118,7 +123,7 @@ bool IDBOpenDBRequest::dispatchEvent(Event& event)
     bool result = IDBRequest::dispatchEvent(event);
 
     if (m_transaction && m_transaction->isVersionChange() && (event.type() == eventNames().errorEvent || event.type() == eventNames().successEvent))
-        m_transaction->database().connectionProxy().didFinishHandlingVersionChangeTransaction(*m_transaction);
+        m_transaction->database().connectionProxy().didFinishHandlingVersionChangeTransaction(m_transaction->database().databaseConnectionIdentifier(), *m_transaction);
 
     return result;
 }
index 4294d73..a15a1dc 100644 (file)
@@ -56,6 +56,8 @@ private:
 
     bool dispatchEvent(Event&) final;
 
+    void cancelForStop() final;
+
     void onError(const IDBResultData&);
     void onSuccess(const IDBResultData&);
     void onUpgradeNeeded(const IDBResultData&);
index 860ea48..ca546f7 100644 (file)
@@ -242,11 +242,18 @@ void IDBRequest::stop()
     ASSERT(currentThread() == m_originThreadID);
     ASSERT(!m_contextStopped);
 
+    cancelForStop();
+
     removeAllEventListeners();
 
     m_contextStopped = true;
 }
 
+void IDBRequest::cancelForStop()
+{
+    // The base IDBRequest class has nothing additional to do here.
+}
+
 void IDBRequest::enqueueEvent(Ref<Event>&& event)
 {
     ASSERT(currentThread() == m_originThreadID);
index 0313184..c93e2f0 100644 (file)
@@ -139,6 +139,7 @@ private:
     const char* activeDOMObjectName() const final;
     bool canSuspendForDocumentSuspension() const final;
     void stop() final;
+    virtual void cancelForStop();
 
     void refEventTarget() final { RefCounted::ref(); }
     void derefEventTarget() final { RefCounted::deref(); }
index 8204dba..ce8c8b0 100644 (file)
@@ -293,6 +293,11 @@ void IDBConnectionProxy::notifyOpenDBRequestBlocked(const IDBResourceIdentifier&
     performCallbackOnCorrectThread(*request, &IDBOpenDBRequest::requestBlocked, oldVersion, newVersion);
 }
 
+void IDBConnectionProxy::openDBRequestCancelled(const IDBRequestData& requestData)
+{
+    callConnectionOnMainThread(&IDBConnectionToServer::openDBRequestCancelled, requestData);
+}
+
 void IDBConnectionProxy::establishTransaction(IDBTransaction& transaction)
 {
     {
@@ -373,9 +378,9 @@ bool IDBConnectionProxy::hasRecordOfTransaction(const IDBTransaction& transactio
     return m_pendingTransactions.contains(identifier) || m_committingTransactions.contains(identifier) || m_abortingTransactions.contains(identifier);
 }
 
-void IDBConnectionProxy::didFinishHandlingVersionChangeTransaction(IDBTransaction& transaction)
+void IDBConnectionProxy::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, IDBTransaction& transaction)
 {
-    callConnectionOnMainThread(&IDBConnectionToServer::didFinishHandlingVersionChangeTransaction, transaction.info().identifier());
+    callConnectionOnMainThread(&IDBConnectionToServer::didFinishHandlingVersionChangeTransaction, databaseConnectionIdentifier, transaction.info().identifier());
 }
 
 void IDBConnectionProxy::databaseConnectionClosed(IDBDatabase& database)
index 16688a6..387d7d0 100644 (file)
@@ -80,6 +80,7 @@ public:
     void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
 
     void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
+    void openDBRequestCancelled(const IDBRequestData&);
 
     void establishTransaction(IDBTransaction&);
     void commitTransaction(IDBTransaction&);
@@ -89,7 +90,7 @@ public:
     void didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
     void didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
 
-    void didFinishHandlingVersionChangeTransaction(IDBTransaction&);
+    void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, IDBTransaction&);
     void databaseConnectionClosed(IDBDatabase&);
 
     void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier);
index 2fe7721..fbe7f41 100644 (file)
@@ -268,12 +268,12 @@ void IDBConnectionToServer::didCommitTransaction(const IDBResourceIdentifier& tr
     m_proxy->didCommitTransaction(transactionIdentifier, error);
 }
 
-void IDBConnectionToServer::didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier& transactionIdentifier)
+void IDBConnectionToServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
 {
     LOG(IndexedDB, "IDBConnectionToServer::didFinishHandlingVersionChangeTransaction");
     ASSERT(isMainThread());
 
-    m_delegate->didFinishHandlingVersionChangeTransaction(transactionIdentifier);
+    m_delegate->didFinishHandlingVersionChangeTransaction(databaseConnectionIdentifier, transactionIdentifier);
 }
 
 void IDBConnectionToServer::abortTransaction(const IDBResourceIdentifier& transactionIdentifier)
@@ -324,6 +324,14 @@ void IDBConnectionToServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifi
     m_proxy->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
 }
 
+void IDBConnectionToServer::openDBRequestCancelled(const IDBRequestData& requestData)
+{
+    LOG(IndexedDB, "IDBConnectionToServer::openDBRequestCancelled");
+    ASSERT(isMainThread());
+
+    m_delegate->openDBRequestCancelled(requestData);
+}
+
 void IDBConnectionToServer::databaseConnectionClosed(uint64_t databaseConnectionIdentifier)
 {
     LOG(IndexedDB, "IDBConnectionToServer::databaseConnectionClosed");
index 0de0f06..d0ce068 100644 (file)
@@ -97,7 +97,7 @@ public:
     void commitTransaction(const IDBResourceIdentifier& transactionIdentifier);
     WEBCORE_EXPORT void didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
 
-    void didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier&);
+    void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier&);
 
     void abortTransaction(const IDBResourceIdentifier& transactionIdentifier);
     WEBCORE_EXPORT void didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
@@ -107,6 +107,7 @@ public:
 
     WEBCORE_EXPORT void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
     WEBCORE_EXPORT void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
+    void openDBRequestCancelled(const IDBRequestData&);
 
     void establishTransaction(uint64_t databaseConnectionIdentifier, const IDBTransactionInfo&);
 
index adc5b8e..2c03d4e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef IDBConnectionToServerDelegate_h
-#define IDBConnectionToServerDelegate_h
+#pragma once
 
 #if ENABLE(INDEXED_DATABASE)
 
@@ -60,7 +59,7 @@ public:
     virtual void openDatabase(const IDBRequestData&) = 0;
     virtual void abortTransaction(const IDBResourceIdentifier&) = 0;
     virtual void commitTransaction(const IDBResourceIdentifier&) = 0;
-    virtual void didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier&) = 0;
+    virtual void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier&) = 0;
     virtual void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&) = 0;
     virtual void deleteObjectStore(const IDBRequestData&, const String& objectStoreName) = 0;
     virtual void clearObjectStore(const IDBRequestData&, uint64_t objectStoreIdentifier) = 0;
@@ -77,6 +76,7 @@ public:
     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 openDBRequestCancelled(const IDBRequestData&) = 0;
 
     virtual void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) = 0;
 
@@ -88,4 +88,3 @@ public:
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
-#endif // IDBConnectionToServerDelegate_h
index 0833857..3fd60a7 100644 (file)
@@ -332,20 +332,20 @@ void IDBServer::commitTransaction(const IDBResourceIdentifier& transactionIdenti
     transaction->commit();
 }
 
-void IDBServer::didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier& transactionIdentifier)
+void IDBServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
 {
-    LOG(IndexedDB, "IDBServer::didFinishHandlingVersionChangeTransaction");
+    LOG(IndexedDB, "IDBServer::didFinishHandlingVersionChangeTransaction - %s", transactionIdentifier.loggingString().utf8().data());
 
-    auto transaction = m_transactions.get(transactionIdentifier);
-    if (!transaction)
+    auto* connection = m_databaseConnections.get(databaseConnectionIdentifier);
+    if (!connection)
         return;
 
-    transaction->didFinishHandlingVersionChange();
+    connection->didFinishHandlingVersionChange(transactionIdentifier);
 }
 
 void IDBServer::databaseConnectionClosed(uint64_t databaseConnectionIdentifier)
 {
-    LOG(IndexedDB, "IDBServer::databaseConnectionClosed");
+    LOG(IndexedDB, "IDBServer::databaseConnectionClosed - %" PRIu64, databaseConnectionIdentifier);
 
     auto databaseConnection = m_databaseConnections.get(databaseConnectionIdentifier);
     if (!databaseConnection)
@@ -377,6 +377,17 @@ void IDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier,
         databaseConnection->didFireVersionChangeEvent(requestIdentifier);
 }
 
+void IDBServer::openDBRequestCancelled(const IDBRequestData& requestData)
+{
+    LOG(IndexedDB, "IDBServer::openDBRequestCancelled");
+
+    auto* uniqueIDBDatabase = m_uniqueIDBDatabaseMap.get(requestData.databaseIdentifier());
+    if (!uniqueIDBDatabase)
+        return;
+
+    uniqueIDBDatabase->openDBRequestCancelled(requestData.requestIdentifier());
+}
+
 void IDBServer::getAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
 {
     postDatabaseTask(createCrossThreadTask(*this, &IDBServer::performGetAllDatabaseNames, serverConnectionIdentifier, mainFrameOrigin, openingOrigin, callbackID));
index b06917a..effa807 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef IDBServer_h
-#define IDBServer_h
+#pragma once
 
 #if ENABLE(INDEXED_DATABASE)
 
@@ -64,7 +63,7 @@ public:
     WEBCORE_EXPORT void deleteDatabase(const IDBRequestData&);
     WEBCORE_EXPORT void abortTransaction(const IDBResourceIdentifier&);
     WEBCORE_EXPORT void commitTransaction(const IDBResourceIdentifier&);
-    WEBCORE_EXPORT void didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier&);
+    WEBCORE_EXPORT void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier&);
     WEBCORE_EXPORT void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&);
     WEBCORE_EXPORT void deleteObjectStore(const IDBRequestData&, const String& objectStoreName);
     WEBCORE_EXPORT void clearObjectStore(const IDBRequestData&, uint64_t objectStoreIdentifier);
@@ -81,6 +80,7 @@ public:
     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 openDBRequestCancelled(const IDBRequestData&);
 
     WEBCORE_EXPORT void getAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID);
 
@@ -131,4 +131,3 @@ private:
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
-#endif // IDBServer_h
index af5bd2f..5b2adcc 100644 (file)
@@ -74,8 +74,7 @@ const IDBDatabaseInfo& UniqueIDBDatabase::info() const
 
 void UniqueIDBDatabase::openDatabaseConnection(IDBConnectionToClient& connection, const IDBRequestData& requestData)
 {
-    auto operation = ServerOpenDBRequest::create(connection, requestData);
-    m_pendingOpenDBRequests.append(WTFMove(operation));
+    m_pendingOpenDBRequests.add(ServerOpenDBRequest::create(connection, requestData));
 
     // An open operation is already in progress, so we can't possibly handle this one yet.
     if (m_isOpeningBackingStore)
@@ -247,13 +246,15 @@ void UniqueIDBDatabase::didDeleteBackingStore(uint64_t deletedVersion)
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::didDeleteBackingStore");
 
-    ASSERT(m_currentOpenDBRequest);
-    ASSERT(m_currentOpenDBRequest->isDeleteRequest());
     ASSERT(!hasAnyPendingCallbacks());
     ASSERT(!hasUnfinishedTransactions());
     ASSERT(m_pendingTransactions.isEmpty());
     ASSERT(m_openDatabaseConnections.isEmpty());
 
+    // It's possible that the openDBRequest was cancelled from client-side after the delete was already dispatched to the backingstore.
+    // So it's okay if we don't have a currentOpenDBRequest, but if we do it has to be a deleteRequest.
+    ASSERT(!m_currentOpenDBRequest || m_currentOpenDBRequest->isDeleteRequest());
+
     if (m_databaseInfo)
         m_mostRecentDeletedDatabaseInfo = WTFMove(m_databaseInfo);
 
@@ -263,23 +264,28 @@ void UniqueIDBDatabase::didDeleteBackingStore(uint64_t deletedVersion)
     if (!m_mostRecentDeletedDatabaseInfo)
         m_mostRecentDeletedDatabaseInfo = std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), deletedVersion);
 
-    m_currentOpenDBRequest->notifyDidDeleteDatabase(*m_mostRecentDeletedDatabaseInfo);
-    m_currentOpenDBRequest = nullptr;
+    if (m_currentOpenDBRequest) {
+        m_currentOpenDBRequest->notifyDidDeleteDatabase(*m_mostRecentDeletedDatabaseInfo);
+        m_currentOpenDBRequest = nullptr;
+    }
 
     m_deleteBackingStoreInProgress = false;
 
-    if (m_closePendingDatabaseConnections.isEmpty()) {
-        if (m_pendingOpenDBRequests.isEmpty())
-            m_server.closeUniqueIDBDatabase(*this);
-        else
-            invokeOperationAndTransactionTimer();
+    if (m_closePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty()) {
+        m_server.closeUniqueIDBDatabase(*this);
+        return;
     }
+
+    invokeOperationAndTransactionTimer();
 }
 
 void UniqueIDBDatabase::handleDatabaseOperations()
 {
     ASSERT(isMainThread());
-    LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDatabaseOperations - There are %zu pending", m_pendingOpenDBRequests.size());
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDatabaseOperations - There are %u pending", m_pendingOpenDBRequests.size());
+
+    if (m_deleteBackingStoreInProgress)
+        return;
 
     if (m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_currentOpenDBRequest) {
         // We can't start any new open-database operations right now, but we might be able to start handling a delete operation.
@@ -297,13 +303,15 @@ void UniqueIDBDatabase::handleDatabaseOperations()
         return;
 
     m_currentOpenDBRequest = m_pendingOpenDBRequests.takeFirst();
-    LOG(IndexedDB, "UniqueIDBDatabase::handleDatabaseOperations - Popped an operation, now there are %zu pending", m_pendingOpenDBRequests.size());
+    LOG(IndexedDB, "UniqueIDBDatabase::handleDatabaseOperations - Popped an operation, now there are %u pending", m_pendingOpenDBRequests.size());
 
     handleCurrentOperation();
 }
 
 void UniqueIDBDatabase::handleCurrentOperation()
 {
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::handleCurrentOperation");
+
     ASSERT(m_currentOpenDBRequest);
 
     RefPtr<UniqueIDBDatabase> protector(this);
@@ -367,7 +375,7 @@ void UniqueIDBDatabase::handleDelete(IDBConnectionToClient& connection, const ID
 {
     LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDelete");
 
-    m_pendingOpenDBRequests.append(ServerOpenDBRequest::create(connection, requestData));
+    m_pendingOpenDBRequests.add(ServerOpenDBRequest::create(connection, requestData));
     handleDatabaseOperations();
 }
 
@@ -467,6 +475,28 @@ void UniqueIDBDatabase::didFireVersionChangeEvent(UniqueIDBDatabaseConnection& c
     notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent(connection.identifier());
 }
 
+void UniqueIDBDatabase::openDBRequestCancelled(const IDBResourceIdentifier& requestIdentifier)
+{
+    LOG(IndexedDB, "UniqueIDBDatabase::openDBRequestCancelled - %s", requestIdentifier.loggingString().utf8().data());
+
+    if (m_currentOpenDBRequest && m_currentOpenDBRequest->requestData().requestIdentifier() == requestIdentifier)
+        m_currentOpenDBRequest = nullptr;
+
+    if (m_versionChangeDatabaseConnection && m_versionChangeDatabaseConnection->openRequestIdentifier() == requestIdentifier) {
+        ASSERT(!m_versionChangeTransaction || m_versionChangeTransaction->databaseConnection().openRequestIdentifier() == requestIdentifier);
+        ASSERT(!m_versionChangeTransaction || &m_versionChangeTransaction->databaseConnection() == m_versionChangeDatabaseConnection);
+
+        connectionClosedFromClient(*m_versionChangeDatabaseConnection);
+    }
+
+    for (auto& request : m_pendingOpenDBRequests) {
+        if (request->requestData().requestIdentifier() == requestIdentifier) {
+            m_pendingOpenDBRequests.remove(request);
+            return;
+        }
+    }
+}
+
 void UniqueIDBDatabase::addOpenDatabaseConnection(Ref<UniqueIDBDatabaseConnection>&& connection)
 {
     ASSERT(!m_openDatabaseConnections.contains(&connection.get()));
@@ -998,13 +1028,19 @@ bool UniqueIDBDatabase::prepareToFinishTransaction(UniqueIDBDatabaseTransaction&
 void UniqueIDBDatabase::commitTransaction(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback)
 {
     ASSERT(isMainThread());
-    LOG(IndexedDB, "(main) UniqueIDBDatabase::commitTransaction");
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::commitTransaction - %s", transaction.info().identifier().loggingString().utf8().data());
 
     ASSERT(&transaction.databaseConnection().database() == this);
 
     uint64_t callbackID = storeCallback(callback);
 
     if (!prepareToFinishTransaction(transaction)) {
+        if (!m_openDatabaseConnections.contains(&transaction.databaseConnection())) {
+            // This database connection is closing or has already closed, so there is no point in messaging back to it about the commit failing.
+            forgetErrorCallback(callbackID);
+            return;
+        }
+
         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to commit transaction that is already finishing") });
         return;
     }
@@ -1015,7 +1051,7 @@ void UniqueIDBDatabase::commitTransaction(UniqueIDBDatabaseTransaction& transact
 void UniqueIDBDatabase::performCommitTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier)
 {
     ASSERT(!isMainThread());
-    LOG(IndexedDB, "(db) UniqueIDBDatabase::performCommitTransaction");
+    LOG(IndexedDB, "(db) UniqueIDBDatabase::performCommitTransaction - %s", transactionIdentifier.loggingString().utf8().data());
 
     IDBError error = m_backingStore->commitTransaction(transactionIdentifier);
     m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCommitTransaction, callbackIdentifier, error, transactionIdentifier));
@@ -1024,7 +1060,7 @@ void UniqueIDBDatabase::performCommitTransaction(uint64_t callbackIdentifier, co
 void UniqueIDBDatabase::didPerformCommitTransaction(uint64_t callbackIdentifier, const IDBError& error, const IDBResourceIdentifier& transactionIdentifier)
 {
     ASSERT(isMainThread());
-    LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformCommitTransaction");
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformCommitTransaction - %s", transactionIdentifier.loggingString().utf8().data());
 
     performErrorCallback(callbackIdentifier, error);
 
@@ -1034,13 +1070,19 @@ void UniqueIDBDatabase::didPerformCommitTransaction(uint64_t callbackIdentifier,
 void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback)
 {
     ASSERT(isMainThread());
-    LOG(IndexedDB, "(main) UniqueIDBDatabase::abortTransaction");
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::abortTransaction - %s", transaction.info().identifier().loggingString().utf8().data());
 
     ASSERT(&transaction.databaseConnection().database() == this);
 
     uint64_t callbackID = storeCallback(callback);
 
     if (!prepareToFinishTransaction(transaction)) {
+        if (!m_openDatabaseConnections.contains(&transaction.databaseConnection())) {
+            // This database connection is closing or has already closed, so there is no point in messaging back to it about the abort failing.
+            forgetErrorCallback(callbackID);
+            return;
+        }
+
         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to abort transaction that is already finishing") });
         return;
     }
@@ -1048,13 +1090,13 @@ void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transacti
     m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performAbortTransaction, callbackID, transaction.info().identifier()));
 }
 
-void UniqueIDBDatabase::didFinishHandlingVersionChange(UniqueIDBDatabaseTransaction& transaction)
+void UniqueIDBDatabase::didFinishHandlingVersionChange(UniqueIDBDatabaseConnection& connection, const IDBResourceIdentifier& transactionIdentifier)
 {
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::didFinishHandlingVersionChange");
 
-    ASSERT(m_versionChangeTransaction);
-    ASSERT_UNUSED(transaction, m_versionChangeTransaction == &transaction);
+    ASSERT_UNUSED(transactionIdentifier, !m_versionChangeTransaction || m_versionChangeTransaction->info().identifier() == transactionIdentifier);
+    ASSERT_UNUSED(connection, !m_versionChangeDatabaseConnection || m_versionChangeDatabaseConnection.get() == &connection);
 
     m_versionChangeTransaction = nullptr;
     m_versionChangeDatabaseConnection = nullptr;
@@ -1065,7 +1107,7 @@ void UniqueIDBDatabase::didFinishHandlingVersionChange(UniqueIDBDatabaseTransact
 void UniqueIDBDatabase::performAbortTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier)
 {
     ASSERT(!isMainThread());
-    LOG(IndexedDB, "(db) UniqueIDBDatabase::performAbortTransaction");
+    LOG(IndexedDB, "(db) UniqueIDBDatabase::performAbortTransaction - %s", transactionIdentifier.loggingString().utf8().data());
 
     IDBError error = m_backingStore->abortTransaction(transactionIdentifier);
     m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformAbortTransaction, callbackIdentifier, error, transactionIdentifier));
@@ -1074,7 +1116,7 @@ void UniqueIDBDatabase::performAbortTransaction(uint64_t callbackIdentifier, con
 void UniqueIDBDatabase::didPerformAbortTransaction(uint64_t callbackIdentifier, const IDBError& error, const IDBResourceIdentifier& transactionIdentifier)
 {
     ASSERT(isMainThread());
-    LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformAbortTransaction");
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformAbortTransaction - %s", transactionIdentifier.loggingString().utf8().data());
 
     auto transaction = m_finishingTransactions.take(transactionIdentifier);
     ASSERT(transaction);
@@ -1100,12 +1142,26 @@ void UniqueIDBDatabase::transactionDestroyed(UniqueIDBDatabaseTransaction& trans
 void UniqueIDBDatabase::connectionClosedFromClient(UniqueIDBDatabaseConnection& connection)
 {
     ASSERT(isMainThread());
-    LOG(IndexedDB, "(main) UniqueIDBDatabase::connectionClosedFromClient");
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::connectionClosedFromClient - %s (%" PRIu64 ")", connection.openRequestIdentifier().loggingString().utf8().data(), connection.identifier());
 
-    if (m_versionChangeDatabaseConnection == &connection)
-        m_versionChangeDatabaseConnection = nullptr;
+    Ref<UniqueIDBDatabaseConnection> protectedConnection(connection);
+    m_openDatabaseConnections.remove(&connection);
+
+    if (m_versionChangeDatabaseConnection == &connection) {
+        if (m_versionChangeTransaction) {
+            m_closePendingDatabaseConnections.add(WTFMove(m_versionChangeDatabaseConnection));
+
+            auto transactionIdentifier = m_versionChangeTransaction->info().identifier();
+            if (m_inProgressTransactions.contains(transactionIdentifier)) {
+                ASSERT(!m_finishingTransactions.contains(transactionIdentifier));
+                connection.abortTransactionWithoutCallback(*m_versionChangeTransaction);
+            }
 
-    ASSERT(m_openDatabaseConnections.contains(&connection));
+            return;
+        }
+
+        m_versionChangeDatabaseConnection = nullptr;
+    }
 
     Deque<RefPtr<UniqueIDBDatabaseTransaction>> pendingTransactions;
     while (!m_pendingTransactions.isEmpty()) {
@@ -1117,14 +1173,11 @@ void UniqueIDBDatabase::connectionClosedFromClient(UniqueIDBDatabaseConnection&
     if (!pendingTransactions.isEmpty())
         m_pendingTransactions.swap(pendingTransactions);
 
-    RefPtr<UniqueIDBDatabaseConnection> refConnection(&connection);
-    m_openDatabaseConnections.remove(&connection);
-
     if (m_currentOpenDBRequest)
         notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent(connection.identifier());
 
     if (connection.hasNonFinishedTransactions()) {
-        m_closePendingDatabaseConnections.add(WTFMove(refConnection));
+        m_closePendingDatabaseConnections.add(WTFMove(protectedConnection));
         return;
     }
 
@@ -1322,6 +1375,9 @@ void UniqueIDBDatabase::transactionCompleted(RefPtr<UniqueIDBDatabaseTransaction
     if (!transaction->databaseConnection().hasNonFinishedTransactions())
         m_closePendingDatabaseConnections.remove(&transaction->databaseConnection());
 
+    if (m_versionChangeTransaction == transaction)
+        m_versionChangeTransaction = nullptr;
+
     // It's possible that this database had its backing store deleted but there were a few outstanding asynchronous operations.
     // If this transaction completing was the last of those operations, we can finally delete this UniqueIDBDatabase.
     if (m_closePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty() && !m_databaseInfo) {
@@ -1361,6 +1417,12 @@ void UniqueIDBDatabase::performCountCallback(uint64_t callbackIdentifier, const
     callback(error, count);
 }
 
+void UniqueIDBDatabase::forgetErrorCallback(uint64_t callbackIdentifier)
+{
+    ASSERT(m_errorCallbacks.contains(callbackIdentifier));
+    m_errorCallbacks.remove(callbackIdentifier);
+}
+
 } // namespace IDBServer
 } // namespace WebCore
 
index af22728..b837e19 100644 (file)
@@ -96,10 +96,11 @@ public:
     void iterateCursor(const IDBRequestData&, const IDBKeyData&, unsigned long count, GetResultCallback);
     void commitTransaction(UniqueIDBDatabaseTransaction&, ErrorCallback);
     void abortTransaction(UniqueIDBDatabaseTransaction&, ErrorCallback);
-    void didFinishHandlingVersionChange(UniqueIDBDatabaseTransaction&);
+    void didFinishHandlingVersionChange(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& transactionIdentifier);
     void transactionDestroyed(UniqueIDBDatabaseTransaction&);
     void connectionClosedFromClient(UniqueIDBDatabaseConnection&);
     void didFireVersionChangeEvent(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier);
+    void openDBRequestCancelled(const IDBResourceIdentifier& requestIdentifier);
 
     void enqueueTransaction(Ref<UniqueIDBDatabaseTransaction>&&);
 
@@ -174,6 +175,8 @@ private:
     void performGetResultCallback(uint64_t callbackIdentifier, const IDBError&, const IDBGetResult&);
     void performCountCallback(uint64_t callbackIdentifier, const IDBError&, uint64_t);
 
+    void forgetErrorCallback(uint64_t callbackIdentifier);
+
     bool hasAnyPendingCallbacks() const;
     bool isCurrentlyInUse() const;
     bool hasUnfinishedTransactions() const;
@@ -187,7 +190,7 @@ private:
     IDBServer& m_server;
     IDBDatabaseIdentifier m_identifier;
     
-    Deque<Ref<ServerOpenDBRequest>> m_pendingOpenDBRequests;
+    ListHashSet<RefPtr<ServerOpenDBRequest>> m_pendingOpenDBRequests;
     RefPtr<ServerOpenDBRequest> m_currentOpenDBRequest;
 
     ListHashSet<RefPtr<UniqueIDBDatabaseConnection>> m_openDatabaseConnections;
index d83e418..ed6e933 100644 (file)
@@ -32,6 +32,7 @@
 #include "IDBServer.h"
 #include "IDBTransactionInfo.h"
 #include "Logging.h"
+#include "ServerOpenDBRequest.h"
 #include "UniqueIDBDatabase.h"
 
 namespace WebCore {
@@ -70,9 +71,14 @@ bool UniqueIDBDatabaseConnection::hasNonFinishedTransactions() const
 void UniqueIDBDatabaseConnection::abortTransactionWithoutCallback(UniqueIDBDatabaseTransaction& transaction)
 {
     ASSERT(m_transactionMap.contains(transaction.info().identifier()));
-    auto takenTransaction = m_transactionMap.take(transaction.info().identifier());
 
-    m_database.abortTransaction(*takenTransaction, [](const IDBError&) { });
+    const auto& transactionIdentifier = transaction.info().identifier();
+    RefPtr<UniqueIDBDatabaseConnection> protector(this);
+
+    m_database.abortTransaction(transaction, [this, protector, transactionIdentifier](const IDBError&) {
+        ASSERT(m_transactionMap.contains(transactionIdentifier));
+        m_transactionMap.remove(transactionIdentifier);
+    });
 }
 
 void UniqueIDBDatabaseConnection::connectionClosedFromClient()
@@ -90,6 +96,13 @@ void UniqueIDBDatabaseConnection::didFireVersionChangeEvent(const IDBResourceIde
     m_database.didFireVersionChangeEvent(*this, requestIdentifier);
 }
 
+void UniqueIDBDatabaseConnection::didFinishHandlingVersionChange(const IDBResourceIdentifier& transactionIdentifier)
+{
+    LOG(IndexedDB, "UniqueIDBDatabaseConnection::didFinishHandlingVersionChange - %s - %" PRIu64, transactionIdentifier.loggingString().utf8().data(), m_identifier);
+
+    m_database.didFinishHandlingVersionChange(*this, transactionIdentifier);
+}
+
 void UniqueIDBDatabaseConnection::fireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion)
 {
     ASSERT(!m_closePending);
index 49b995a..ed12349 100644 (file)
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef UniqueIDBDatabaseConnection_h
-#define UniqueIDBDatabaseConnection_h
+#pragma once
 
 #if ENABLE(INDEXED_DATABASE)
 
@@ -74,6 +73,7 @@ public:
     void didCreateIndex(const IDBResultData&);
     void didDeleteIndex(const IDBResultData&);
     void didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier);
+    void didFinishHandlingVersionChange(const IDBResourceIdentifier& transactionIdentifier);
 
     void abortTransactionWithoutCallback(UniqueIDBDatabaseTransaction&);
 
@@ -94,4 +94,3 @@ private:
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
-#endif // UniqueIDBDatabaseConnection_h
index d6e2aec..d955ae6 100644 (file)
@@ -316,14 +316,6 @@ void UniqueIDBDatabaseTransaction::didActivateInBackingStore(const IDBError& err
     m_databaseConnection->connectionToClient().didStartTransaction(m_transactionInfo.identifier(), error);
 }
 
-void UniqueIDBDatabaseTransaction::didFinishHandlingVersionChange()
-{
-    LOG(IndexedDB, "UniqueIDBDatabaseTransaction::didFinishHandlingVersionChange");
-    ASSERT(isVersionChange());
-
-    m_databaseConnection->database().didFinishHandlingVersionChange(*this);
-}
-
 } // namespace IDBServer
 } // namespace WebCore
 
index 76d87c9..88da017 100644 (file)
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef UniqueIDBDatabaseTransaction_h
-#define UniqueIDBDatabaseTransaction_h
+#pragma once
 
 #if ENABLE(INDEXED_DATABASE)
 
@@ -80,7 +79,6 @@ public:
     void iterateCursor(const IDBRequestData&, const IDBKeyData&, unsigned long count);
 
     void didActivateInBackingStore(const IDBError&);
-    void didFinishHandlingVersionChange();
 
     const Vector<uint64_t>& objectStoreIdentifiers();
 
@@ -99,4 +97,3 @@ private:
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
-#endif // UniqueIDBDatabaseTransaction_h
index 0ff41bd..93ac6d6 100644 (file)
@@ -241,11 +241,11 @@ void InProcessIDBServer::commitTransaction(const IDBResourceIdentifier& resource
     });
 }
 
-void InProcessIDBServer::didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier& transactionIdentifier)
+void InProcessIDBServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
 {
     RefPtr<InProcessIDBServer> self(this);
-    RunLoop::current().dispatch([this, self, transactionIdentifier] {
-        m_server->didFinishHandlingVersionChangeTransaction(transactionIdentifier);
+    RunLoop::current().dispatch([this, self, databaseConnectionIdentifier, transactionIdentifier] {
+        m_server->didFinishHandlingVersionChangeTransaction(databaseConnectionIdentifier, transactionIdentifier);
     });
 }
 
@@ -399,6 +399,14 @@ void InProcessIDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionId
     });
 }
 
+void InProcessIDBServer::openDBRequestCancelled(const IDBRequestData& requestData)
+{
+    RefPtr<InProcessIDBServer> self(this);
+    RunLoop::current().dispatch([this, self, requestData] {
+        m_server->openDBRequestCancelled(requestData);
+    });
+}
+
 void InProcessIDBServer::getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
 {
     RefPtr<InProcessIDBServer> protector(this);
index df34315..93a3f49 100644 (file)
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef InProcessIDBServer_h
-#define InProcessIDBServer_h
+#pragma once
 
 #if ENABLE(INDEXED_DATABASE)
 
@@ -59,7 +58,7 @@ public:
     void openDatabase(const IDBRequestData&) final;
     void abortTransaction(const IDBResourceIdentifier&) final;
     void commitTransaction(const IDBResourceIdentifier&) final;
-    void didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier&) final;
+    void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier&) final;
     void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&) final;
     void deleteObjectStore(const IDBRequestData&, const String& objectStoreName) final;
     void clearObjectStore(const IDBRequestData&, uint64_t objectStoreIdentifier) final;
@@ -75,6 +74,7 @@ public:
     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 openDBRequestCancelled(const IDBRequestData&) final;
     void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) final;
 
     // IDBConnectionToClient
@@ -117,4 +117,3 @@ private:
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
-#endif // InProcessIDBServer_h
index 4acaed7..077bca7 100644 (file)
@@ -1,3 +1,21 @@
+2016-05-11  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: IDBOpenDBRequests that are stop()'ed don't notify the IDBServer of that fact.
+        https://bugs.webkit.org/show_bug.cgi?id=157448
+
+        Reviewed by Alex Christensen.
+
+        * DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp:
+        (WebKit::WebIDBConnectionToClient::didFinishHandlingVersionChangeTransaction):
+        (WebKit::WebIDBConnectionToClient::openDBRequestCancelled):
+        * DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h:
+        * DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in:
+
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
+        (WebKit::WebIDBConnectionToServer::didFinishHandlingVersionChangeTransaction):
+        (WebKit::WebIDBConnectionToServer::openDBRequestCancelled):
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h:
+
 2016-05-11  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Fix a typo in r200330
index fc51c50..d1c1b3d 100644 (file)
@@ -199,9 +199,9 @@ void WebIDBConnectionToClient::commitTransaction(const IDBResourceIdentifier& tr
     DatabaseProcess::singleton().idbServer().commitTransaction(transactionIdentifier);
 }
 
-void WebIDBConnectionToClient::didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier& transactionIdentifier)
+void WebIDBConnectionToClient::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
 {
-    DatabaseProcess::singleton().idbServer().didFinishHandlingVersionChangeTransaction(transactionIdentifier);
+    DatabaseProcess::singleton().idbServer().didFinishHandlingVersionChangeTransaction(databaseConnectionIdentifier, transactionIdentifier);
 }
 
 void WebIDBConnectionToClient::createObjectStore(const IDBRequestData& request, const IDBObjectStoreInfo& info)
@@ -289,6 +289,11 @@ void WebIDBConnectionToClient::didFireVersionChangeEvent(uint64_t databaseConnec
     DatabaseProcess::singleton().idbServer().didFireVersionChangeEvent(databaseConnectionIdentifier, transactionIdentifier);
 }
 
+void WebIDBConnectionToClient::openDBRequestCancelled(const IDBRequestData& requestData)
+{
+    DatabaseProcess::singleton().idbServer().openDBRequestCancelled(requestData);
+}
+
 void WebIDBConnectionToClient::getAllDatabaseNames(uint64_t serverConnectionIdentifier, const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID)
 {
     DatabaseProcess::singleton().idbServer().getAllDatabaseNames(serverConnectionIdentifier, topOrigin, openingOrigin, callbackID);
index fdca0bf..ffb8096 100644 (file)
@@ -88,7 +88,7 @@ public:
     void openDatabase(const WebCore::IDBRequestData&);
     void abortTransaction(const WebCore::IDBResourceIdentifier&);
     void commitTransaction(const WebCore::IDBResourceIdentifier&);
-    void didFinishHandlingVersionChangeTransaction(const WebCore::IDBResourceIdentifier&);
+    void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier&);
     void createObjectStore(const WebCore::IDBRequestData&, const WebCore::IDBObjectStoreInfo&);
     void deleteObjectStore(const WebCore::IDBRequestData&, const String& objectStoreName);
     void clearObjectStore(const WebCore::IDBRequestData&, uint64_t objectStoreIdentifier);
@@ -105,6 +105,7 @@ public:
     void databaseConnectionClosed(uint64_t databaseConnectionIdentifier);
     void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier);
     void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier);
+    void openDBRequestCancelled(const WebCore::IDBRequestData&);
 
     void getAllDatabaseNames(uint64_t serverConnectionIdentifier, const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID);
 
index 335ca71..ff92808 100644 (file)
@@ -27,7 +27,7 @@ messages -> WebIDBConnectionToClient {
     OpenDatabase(WebCore::IDBRequestData requestData);
     AbortTransaction(WebCore::IDBResourceIdentifier transactionIdentifier);
     CommitTransaction(WebCore::IDBResourceIdentifier transactionIdentifier);
-    DidFinishHandlingVersionChangeTransaction(WebCore::IDBResourceIdentifier transactionIdentifier);
+    DidFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier transactionIdentifier);
     CreateObjectStore(WebCore::IDBRequestData requestData, WebCore::IDBObjectStoreInfo info);
     DeleteObjectStore(WebCore::IDBRequestData requestData, String objectStoreName);
     ClearObjectStore(WebCore::IDBRequestData requestData, uint64_t objectStoreIdentifier);
@@ -44,6 +44,7 @@ messages -> WebIDBConnectionToClient {
     DatabaseConnectionClosed(uint64_t databaseConnectionIdentifier);
     AbortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier transactionIdentifier);
     DidFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier requestIdentifier);
+    OpenDBRequestCancelled(WebCore::IDBRequestData requestData);
 
     GetAllDatabaseNames(uint64_t serverConnectionIdentifier, struct WebCore::SecurityOriginData topOrigin, struct WebCore::SecurityOriginData openingOrigin, uint64_t callbackID);
 }
index fe0a8ff..507f266 100644 (file)
@@ -101,9 +101,9 @@ void WebIDBConnectionToServer::commitTransaction(const IDBResourceIdentifier& tr
     send(Messages::WebIDBConnectionToClient::CommitTransaction(transactionIdentifier));
 }
 
-void WebIDBConnectionToServer::didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier& transactionIdentifier)
+void WebIDBConnectionToServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
 {
-    send(Messages::WebIDBConnectionToClient::DidFinishHandlingVersionChangeTransaction(transactionIdentifier));
+    send(Messages::WebIDBConnectionToClient::DidFinishHandlingVersionChangeTransaction(databaseConnectionIdentifier, transactionIdentifier));
 }
 
 void WebIDBConnectionToServer::createObjectStore(const IDBRequestData& requestData, const IDBObjectStoreInfo& info)
@@ -181,6 +181,11 @@ void WebIDBConnectionToServer::didFireVersionChangeEvent(uint64_t databaseConnec
     send(Messages::WebIDBConnectionToClient::DidFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier));
 }
 
+void WebIDBConnectionToServer::openDBRequestCancelled(const IDBRequestData& requestData)
+{
+    send(Messages::WebIDBConnectionToClient::OpenDBRequestCancelled(requestData));
+}
+
 void WebIDBConnectionToServer::getAllDatabaseNames(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID)
 {
     send(Messages::WebIDBConnectionToClient::GetAllDatabaseNames(m_identifier, topOrigin, openingOrigin, callbackID));
index 25d1021..1164b56 100644 (file)
@@ -49,7 +49,7 @@ public:
     void openDatabase(const WebCore::IDBRequestData&) final;
     void abortTransaction(const WebCore::IDBResourceIdentifier&) final;
     void commitTransaction(const WebCore::IDBResourceIdentifier&) final;
-    void didFinishHandlingVersionChangeTransaction(const WebCore::IDBResourceIdentifier&) final;
+    void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier&) final;
     void createObjectStore(const WebCore::IDBRequestData&, const WebCore::IDBObjectStoreInfo&) final;
     void deleteObjectStore(const WebCore::IDBRequestData&, const String& objectStoreName) final;
     void clearObjectStore(const WebCore::IDBRequestData&, uint64_t objectStoreIdentifier) final;
@@ -65,6 +65,8 @@ public:
     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 openDBRequestCancelled(const WebCore::IDBRequestData&) final;
+
     void getAllDatabaseNames(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID) final;
 
     void ref() override { RefCounted<WebIDBConnectionToServer>::ref(); }