Diff
Modified: trunk/LayoutTests/ChangeLog (201097 => 201098)
--- trunk/LayoutTests/ChangeLog 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/LayoutTests/ChangeLog 2016-05-18 20:42:20 UTC (rev 201098)
@@ -1,3 +1,14 @@
+2016-05-18 Brady Eidson <beid...@apple.com>
+
+ Modern IDB: Add support for server side closing of open database connections.
+ https://bugs.webkit.org/show_bug.cgi?id=157843
+
+ Reviewed by Alex Christensen.
+
+ * storage/indexeddb/modern/handle-user-delete-expected.txt: Added.
+ * storage/indexeddb/modern/handle-user-delete.html: Added.
+ * storage/indexeddb/modern/resources/handle-user-delete.js: Added.
+
2016-05-18 Myles C. Maxfield <mmaxfi...@apple.com>
[OS X] Update platform/mac/fast/text/sticky-typesetting-features.html
Added: trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete-expected.txt (0 => 201098)
--- trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete-expected.txt (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete-expected.txt 2016-05-18 20:42:20 UTC (rev 201098)
@@ -0,0 +1,19 @@
+Tests that expected errors come back from user delete.
+
+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;
+
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+Initial upgrade needed: Old version - 0 New version - 1
+Started two spinning requests
+Requested clearAllDatabases
+Initial upgrade versionchange transaction aborted: [object DOMError]
+[PASS] Both requests hit a failure condition (Received onerror or failed to start a new request because the transaction was aborted)
+[PASS] Database received correct error.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete.html (0 => 201098)
--- trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete.html (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete.html 2016-05-18 20:42:20 UTC (rev 201098)
@@ -0,0 +1,10 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/storage/indexeddb/modern/resources/handle-user-delete.js (0 => 201098)
--- trunk/LayoutTests/storage/indexeddb/modern/resources/handle-user-delete.js (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/resources/handle-user-delete.js 2016-05-18 20:42:20 UTC (rev 201098)
@@ -0,0 +1,92 @@
+description("Tests that expected errors come back from user delete.");
+
+indexedDBTest(prepareDatabase);
+
+var requestErrorCount = 0;
+var databaseError = false;
+
+function done()
+{
+ if (requestErrorCount == 2)
+ log("[PASS] Both requests hit a failure condition (Received onerror or failed to start a new request because the transaction was aborted)");
+ else
+ log("[FAIL] " + requestErrorCount + " request(s) hit a failure condition.");
+
+ if (databaseError)
+ log("[PASS] Database received correct error.");
+ else
+ log("[FAIL] Database did not receive correct error.");
+
+ finishJSTest();
+}
+
+function log(message)
+{
+ debug(message);
+}
+
+function maybeFinish()
+{
+ if (requestErrorCount == 2 && databaseError)
+ done();
+}
+
+function prepareDatabase(event)
+{
+ log("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+ var versionTransaction = event.target.transaction;
+ var database = event.target.result;
+ var objectStore = database.createObjectStore("TestObjectStore");
+ objectStore.put("bar", "foo");
+
+ database._onerror_ = function(event) {
+ databaseError = true;
+ maybeFinish();
+ }
+
+ var hasClearedDatabases = false;
+ var spinGet = function() {
+ try {
+ var req = objectStore.get("foo");
+ } catch(e) {
+ ++requestErrorCount;
+ maybeFinish();
+ return;
+ }
+ req._onsuccess_ = function() {
+ spinGet();
+ if (!hasClearedDatabases) {
+ if (window.testRunner) {
+ setTimeout("testRunner.clearAllDatabases();", 0);
+ log("Requested clearAllDatabases");
+ }
+ hasClearedDatabases = true;
+ }
+ }
+ req._onerror_ = function(event) {
+ ++requestErrorCount;
+ event.stopImmediatePropagation();
+ maybeFinish();
+ }
+ }
+ // Start up two get cycles so there will always be at least one request to cancel when the database is deleted.
+ spinGet();
+ spinGet();
+
+ log("Started two spinning requests")
+
+ versionTransaction._onabort_ = function(event) {
+ log("Initial upgrade versionchange transaction aborted: " + versionTransaction.error);
+ }
+
+ versionTransaction._oncomplete_ = function() {
+ log("Initial upgrade versionchange transaction unexpected complete");
+ done();
+ }
+
+ versionTransaction._onerror_ = function(event) {
+ log("Initial upgrade versionchange transaction unexpected error: " + event.type + " " + versionTransaction.error.name + ", " + versionTransaction.error.message);
+ done();
+ }
+}
Modified: trunk/Source/WebCore/ChangeLog (201097 => 201098)
--- trunk/Source/WebCore/ChangeLog 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/ChangeLog 2016-05-18 20:42:20 UTC (rev 201098)
@@ -1,3 +1,136 @@
+2016-05-18 Brady Eidson <beid...@apple.com>
+
+ Modern IDB: Add support for server side closing of open database connections.
+ https://bugs.webkit.org/show_bug.cgi?id=157843
+
+ Reviewed by Alex Christensen.
+
+ Test: storage/indexeddb/modern/handle-user-delete.html
+
+ In order to support deleting IndexedDB databases, the IDB server needs the ability to
+ "immediately" close a currently open IDB connection.
+
+ To do so cleanly, the server has to:
+ - Error out all requests it knows about
+ - Abort all transactions it knows about
+ - Tell the connection that it is being closed
+ - Wait for the connection to acknowledge that it was closed on the server
+
+ And then the client has to:
+ - Error out all requests it hasn't sent to the server
+ - Abort all transactions that haven't already been aborted by the server
+ - Send acknowledgement to the server that it has been closed.
+
+ Finally, because the status of a given request might be "in flight" somewhere between the
+ server and the client, some design assumptions change. This requires reworking some ASSERTS,
+ null checks, etc.
+
+ * Modules/indexeddb/IDBDatabase.cpp:
+ (WebCore::IDBDatabase::didCloseFromServer): Do the heavy lifting for the immediate close on
+ the client side.
+ * Modules/indexeddb/IDBDatabase.h:
+
+ * Modules/indexeddb/IDBDatabaseIdentifier.h:
+ (WebCore::IDBDatabaseIdentifier::isRelatedToOrigin):
+
+ * Modules/indexeddb/IDBTransaction.cpp:
+ (WebCore::IDBTransaction::connectionClosedFromServer): Error out all outstanding operations
+ and fire the abort error on itself.
+ * Modules/indexeddb/IDBTransaction.h:
+
+ * Modules/indexeddb/client/IDBConnectionProxy.cpp:
+ (WebCore::IDBClient::IDBConnectionProxy::completeOperation):
+ (WebCore::IDBClient::IDBConnectionProxy::didCloseFromServer):
+ (WebCore::IDBClient::IDBConnectionProxy::confirmDidCloseFromServer):
+ (WebCore::IDBClient::IDBConnectionProxy::forgetActiveOperations):
+ * Modules/indexeddb/client/IDBConnectionProxy.h:
+
+ * Modules/indexeddb/client/IDBConnectionToServer.cpp:
+ (WebCore::IDBClient::IDBConnectionToServer::didCloseFromServer):
+ (WebCore::IDBClient::IDBConnectionToServer::confirmDidCloseFromServer):
+ * Modules/indexeddb/client/IDBConnectionToServer.h:
+ * Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
+
+ * Modules/indexeddb/server/IDBConnectionToClient.cpp:
+ (WebCore::IDBServer::IDBConnectionToClient::didCloseFromServer):
+ * Modules/indexeddb/server/IDBConnectionToClient.h:
+ * Modules/indexeddb/server/IDBConnectionToClientDelegate.h:
+
+ * Modules/indexeddb/server/IDBServer.cpp:
+ (WebCore::IDBServer::IDBServer::confirmDidCloseFromServer):
+ (WebCore::IDBServer::generateDeleteCallbackID):
+ (WebCore::IDBServer::IDBServer::closeAndDeleteDatabasesModifiedSince):
+ (WebCore::IDBServer::IDBServer::closeAndDeleteDatabasesForOrigins):
+ (WebCore::IDBServer::IDBServer::performCloseAndDeleteDatabasesModifiedSince):
+ (WebCore::IDBServer::IDBServer::performCloseAndDeleteDatabasesForOrigins):
+ (WebCore::IDBServer::IDBServer::didPerformCloseAndDeleteDatabases):
+ * Modules/indexeddb/server/IDBServer.h:
+
+ * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+ (WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase):
+ (WebCore::IDBServer::UniqueIDBDatabase::openDatabaseConnection):
+ (WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore):
+ (WebCore::IDBServer::UniqueIDBDatabase::handleDatabaseOperations):
+ (WebCore::IDBServer::UniqueIDBDatabase::handleCurrentOperation):
+ (WebCore::IDBServer::UniqueIDBDatabase::handleDelete):
+ (WebCore::IDBServer::UniqueIDBDatabase::createObjectStore):
+ (WebCore::IDBServer::UniqueIDBDatabase::deleteObjectStore):
+ (WebCore::IDBServer::UniqueIDBDatabase::clearObjectStore):
+ (WebCore::IDBServer::UniqueIDBDatabase::createIndex):
+ (WebCore::IDBServer::UniqueIDBDatabase::deleteIndex):
+ (WebCore::IDBServer::UniqueIDBDatabase::putOrAdd):
+ (WebCore::IDBServer::UniqueIDBDatabase::getRecord):
+ (WebCore::IDBServer::UniqueIDBDatabase::getCount):
+ (WebCore::IDBServer::UniqueIDBDatabase::deleteRecord):
+ (WebCore::IDBServer::UniqueIDBDatabase::openCursor):
+ (WebCore::IDBServer::UniqueIDBDatabase::iterateCursor):
+ (WebCore::IDBServer::UniqueIDBDatabase::commitTransaction):
+ (WebCore::IDBServer::UniqueIDBDatabase::abortTransaction):
+ (WebCore::IDBServer::UniqueIDBDatabase::connectionClosedFromClient):
+ (WebCore::IDBServer::UniqueIDBDatabase::connectionClosedFromServer):
+ (WebCore::IDBServer::UniqueIDBDatabase::confirmDidCloseFromServer):
+ (WebCore::IDBServer::UniqueIDBDatabase::enqueueTransaction):
+ (WebCore::IDBServer::UniqueIDBDatabase::isCurrentlyInUse):
+ (WebCore::IDBServer::UniqueIDBDatabase::invokeOperationAndTransactionTimer):
+ (WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired):
+ (WebCore::IDBServer::UniqueIDBDatabase::activateTransactionInBackingStore):
+ (WebCore::IDBServer::UniqueIDBDatabase::transactionCompleted):
+ (WebCore::IDBServer::UniqueIDBDatabase::postDatabaseTask):
+ (WebCore::IDBServer::UniqueIDBDatabase::postDatabaseTaskReply):
+ (WebCore::IDBServer::UniqueIDBDatabase::executeNextDatabaseTask):
+ (WebCore::IDBServer::UniqueIDBDatabase::executeNextDatabaseTaskReply):
+ (WebCore::IDBServer::UniqueIDBDatabase::doneWithHardClose):
+ (WebCore::IDBServer::errorOpenDBRequestForUserDelete):
+ (WebCore::IDBServer::UniqueIDBDatabase::immediateCloseForUserDelete): Do the heavy lifting
+ for the immediate close on the server side.
+ (WebCore::IDBServer::UniqueIDBDatabase::performErrorCallback):
+ (WebCore::IDBServer::UniqueIDBDatabase::performKeyDataCallback):
+ (WebCore::IDBServer::UniqueIDBDatabase::performGetResultCallback):
+ (WebCore::IDBServer::UniqueIDBDatabase::performCountCallback):
+ (WebCore::IDBServer::UniqueIDBDatabase::storeCallback): Deleted.
+ (WebCore::IDBServer::UniqueIDBDatabase::storeCallbackOrFireError): If the database has been
+ hard stopped, immediately fire and error for the callback and return a 0-identifier to
+ reflect this.
+ * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
+ * Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
+ (WebCore::IDBServer::UniqueIDBDatabaseConnection::confirmDidCloseFromServer):
+ * Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
+
+ * Modules/indexeddb/shared/IDBError.cpp:
+ (WebCore::IDBError::toDOMError):
+ * Modules/indexeddb/shared/IDBError.h:
+ (WebCore::IDBError::userDeleteError):
+
+ * Modules/indexeddb/shared/InProcessIDBServer.cpp:
+ (WebCore::InProcessIDBServer::didCloseFromServer):
+ (WebCore::InProcessIDBServer::confirmDidCloseFromServer):
+ * Modules/indexeddb/shared/InProcessIDBServer.h:
+
+ * platform/CrossThreadCopier.cpp:
+ (WebCore::std::chrono::system_clock::time_point>::copy):
+ * platform/CrossThreadCopier.h:
+
2016-05-18 Simon Fraser <simon.fra...@apple.com>
REGRESSION (r200534) Command-+ no longer zooms pages
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -245,6 +245,25 @@
maybeCloseInServer();
}
+void IDBDatabase::didCloseFromServer(const IDBError& error)
+{
+ LOG(IndexedDB, "IDBDatabase::didCloseFromServer - %" PRIu64, m_databaseConnectionIdentifier);
+
+ ASSERT(currentThread() == m_originThreadID);
+
+ m_closePending = true;
+ m_closedInServer = true;
+
+ for (auto& transaction : m_activeTransactions.values())
+ transaction->connectionClosedFromServer(error);
+
+ Ref<Event> event = Event::create(eventNames().errorEvent, true, false);
+ event->setTarget(this);
+ scriptExecutionContext()->eventQueue().enqueueEvent(WTFMove(event));
+
+ m_connectionProxy->confirmDidCloseFromServer(*this);
+}
+
void IDBDatabase::maybeCloseInServer()
{
LOG(IndexedDB, "IDBDatabase::maybeCloseInServer - %" PRIu64, m_databaseConnectionIdentifier);
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -86,6 +86,7 @@
void didAbortTransaction(IDBTransaction&);
void fireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
+ void didCloseFromServer(const IDBError&);
IDBClient::IDBConnectionProxy& connectionProxy() { return m_connectionProxy.get(); }
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseIdentifier.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseIdentifier.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseIdentifier.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -102,6 +102,11 @@
String debugString() const;
#endif
+ bool isRelatedToOrigin(const SecurityOriginData& other) const
+ {
+ return m_openingOrigin == other || m_mainFrameOrigin == other;
+ }
+
private:
String m_databaseName;
SecurityOriginData m_openingOrigin;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -1075,6 +1075,29 @@
return m_database->originThreadID();
}
+void IDBTransaction::connectionClosedFromServer(const IDBError& error)
+{
+ LOG(IndexedDB, "IDBTransaction::connectionClosedFromServer - %s", error.message().utf8().data());
+
+ m_state = IndexedDB::TransactionState::Aborting;
+
+ Vector<RefPtr<IDBClient::TransactionOperation>> operations;
+ copyValuesToVector(m_transactionOperationMap, operations);
+
+ for (auto& operation : operations)
+ operation->completed(IDBResultData::error(operation->identifier(), error));
+
+ connectionProxy().forgetActiveOperations(operations);
+
+ m_transactionOperationQueue.clear();
+ m_abortQueue.clear();
+ m_transactionOperationMap.clear();
+
+ m_idbError = error;
+ m_domError = error.toDOMError();
+ fireOnAbort();
+}
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -145,6 +145,8 @@
ThreadIdentifier originThreadID() const;
+ void connectionClosedFromServer(const IDBError&);
+
private:
IDBTransaction(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest*);
Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -249,7 +249,8 @@
operation = m_activeOperations.take(resultData.requestIdentifier());
}
- ASSERT(operation);
+ if (!operation)
+ return;
performCallbackOnCorrectThread(*operation, &TransactionOperation::completed, resultData);
}
@@ -388,6 +389,29 @@
callConnectionOnMainThread(&IDBConnectionToServer::databaseConnectionClosed, database.databaseConnectionIdentifier());
}
+void IDBConnectionProxy::didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError& error)
+{
+ RefPtr<IDBDatabase> database;
+ {
+ Locker<Lock> locker(m_databaseConnectionMapLock);
+ database = m_databaseConnectionMap.get(databaseConnectionIdentifier);
+ }
+
+ // If the IDBDatabase object is gone, message back to the server so it doesn't hang
+ // waiting for a reply that will never come.
+ if (!database) {
+ m_connectionToServer.confirmDidCloseFromServer(databaseConnectionIdentifier);
+ return;
+ }
+
+ performCallbackOnCorrectThread(*database, &IDBDatabase::didCloseFromServer, error);
+}
+
+void IDBConnectionProxy::confirmDidCloseFromServer(IDBDatabase& database)
+{
+ callConnectionOnMainThread(&IDBConnectionToServer::confirmDidCloseFromServer, database.databaseConnectionIdentifier());
+}
+
void IDBConnectionProxy::scheduleMainThreadTasks()
{
Locker<Lock> locker(m_mainThreadTaskLock);
@@ -438,6 +462,14 @@
m_databaseConnectionMap.remove(database.databaseConnectionIdentifier());
}
+void IDBConnectionProxy::forgetActiveOperations(const Vector<RefPtr<TransactionOperation>>& operations)
+{
+ Locker<Lock> locker(m_transactionOperationLock);
+
+ for (auto& operation : operations)
+ m_activeOperations.remove(operation->identifier());
+}
+
} // namesapce IDBClient
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -93,6 +93,9 @@
void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, IDBTransaction&);
void databaseConnectionClosed(IDBDatabase&);
+ void didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError&);
+ void confirmDidCloseFromServer(IDBDatabase&);
+
void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier);
void completeOperation(const IDBResultData&);
@@ -109,6 +112,8 @@
RefPtr<IDBOpenDBRequest> takeIDBOpenDBRequest(IDBOpenDBRequest&);
+ void forgetActiveOperations(const Vector<RefPtr<TransactionOperation>>&);
+
private:
void completeOpenDBRequest(const IDBResultData&);
bool hasRecordOfTransaction(const IDBTransaction&) const;
Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -316,6 +316,22 @@
m_proxy->didStartTransaction(transactionIdentifier, error);
}
+void IDBConnectionToServer::didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError& error)
+{
+ LOG(IndexedDB, "IDBConnectionToServer::didCloseFromServer");
+ ASSERT(isMainThread());
+
+ m_proxy->didCloseFromServer(databaseConnectionIdentifier, error);
+}
+
+void IDBConnectionToServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
+{
+ LOG(IndexedDB, "IDBConnectionToServer::confirmDidCloseFromServer");
+ ASSERT(isMainThread());
+
+ m_delegate->confirmDidCloseFromServer(databaseConnectionIdentifier);
+}
+
void IDBConnectionToServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
{
LOG(IndexedDB, "IDBConnectionToServer::didStartTransaction");
Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -106,6 +106,10 @@
void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
WEBCORE_EXPORT void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
+
+ WEBCORE_EXPORT void didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError&);
+ void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
+
WEBCORE_EXPORT void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
void openDBRequestCancelled(const IDBRequestData&);
Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -77,6 +77,7 @@
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 confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier) = 0;
virtual void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) = 0;
Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -133,6 +133,11 @@
m_delegate->didStartTransaction(transactionIdentifier, error);
}
+void IDBConnectionToClient::didCloseFromServer(UniqueIDBDatabaseConnection& connection, const IDBError& error)
+{
+ m_delegate->didCloseFromServer(connection, error);
+}
+
void IDBConnectionToClient::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
{
m_delegate->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -66,6 +66,7 @@
void fireVersionChangeEvent(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
+ void didCloseFromServer(UniqueIDBDatabaseConnection&, const IDBError&);
void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -65,6 +65,7 @@
virtual void fireVersionChangeEvent(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion) = 0;
virtual void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) = 0;
+ virtual void didCloseFromServer(UniqueIDBDatabaseConnection&, const IDBError&) = 0;
virtual void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) = 0;
virtual void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) = 0;
Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -33,7 +33,9 @@
#include "IDBResultData.h"
#include "Logging.h"
#include "MemoryIDBBackingStore.h"
+#include "SQLiteFileSystem.h"
#include "SQLiteIDBBackingStore.h"
+#include "SecurityOrigin.h"
#include <wtf/Locker.h>
#include <wtf/MainThread.h>
@@ -388,6 +390,14 @@
uniqueIDBDatabase->openDBRequestCancelled(requestData.requestIdentifier());
}
+void IDBServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
+{
+ LOG(IndexedDB, "IDBServer::confirmDidCloseFromServer");
+
+ if (auto databaseConnection = m_databaseConnections.get(databaseConnectionIdentifier))
+ databaseConnection->confirmDidCloseFromServer();
+}
+
void IDBServer::getAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
{
postDatabaseTask(createCrossThreadTask(*this, &IDBServer::performGetAllDatabaseNames, serverConnectionIdentifier, mainFrameOrigin, openingOrigin, callbackID));
@@ -468,12 +478,77 @@
task->performTask();
}
-void IDBServer::closeAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point, std::function<void ()> completionHandler)
+static uint64_t generateDeleteCallbackID()
{
- // FIXME: Implement (https://bugs.webkit.org/show_bug.cgi?id=157626)
- completionHandler();
+ ASSERT(isMainThread());
+ static uint64_t currentID = 0;
+ return ++currentID;
}
+void IDBServer::closeAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point modificationTime, std::function<void ()> completionHandler)
+{
+ uint64_t callbackID = generateDeleteCallbackID();
+ auto addResult = m_deleteDatabaseCompletionHandlers.add(callbackID, WTFMove(completionHandler));
+ ASSERT_UNUSED(addResult, addResult.isNewEntry);
+
+ // If the modification time is in the future, don't both doing anything.
+ if (modificationTime > std::chrono::system_clock::now()) {
+ postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didPerformCloseAndDeleteDatabases, callbackID));
+ return;
+ }
+
+ HashSet<UniqueIDBDatabase*> openDatabases;
+ for (auto* connection : m_databaseConnections.values())
+ openDatabases.add(&connection->database());
+
+ for (auto* database : openDatabases)
+ database->immediateCloseForUserDelete();
+
+ postDatabaseTask(createCrossThreadTask(*this, &IDBServer::performCloseAndDeleteDatabasesModifiedSince, modificationTime, callbackID));
+}
+
+void IDBServer::closeAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>& origins, std::function<void ()> completionHandler)
+{
+ uint64_t callbackID = generateDeleteCallbackID();
+ auto addResult = m_deleteDatabaseCompletionHandlers.add(callbackID, WTFMove(completionHandler));
+ ASSERT_UNUSED(addResult, addResult.isNewEntry);
+
+ HashSet<UniqueIDBDatabase*> openDatabases;
+ for (auto* connection : m_databaseConnections.values()) {
+ const auto& identifier = connection->database().identifier();
+ for (auto& origin : origins) {
+ if (identifier.isRelatedToOrigin(origin)) {
+ openDatabases.add(&connection->database());
+ break;
+ }
+ }
+ }
+
+ for (auto* database : openDatabases)
+ database->immediateCloseForUserDelete();
+
+ postDatabaseTask(createCrossThreadTask(*this, &IDBServer::performCloseAndDeleteDatabasesForOrigins, origins, callbackID));
+}
+
+void IDBServer::performCloseAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point, uint64_t callbackID)
+{
+ // FIXME: Implement deleting the files.
+ postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didPerformCloseAndDeleteDatabases, callbackID));
+}
+
+void IDBServer::performCloseAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>&, uint64_t callbackID)
+{
+ // FIXME: Implement deleting the files.
+ postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didPerformCloseAndDeleteDatabases, callbackID));
+}
+
+void IDBServer::didPerformCloseAndDeleteDatabases(uint64_t callbackID)
+{
+ auto callback = m_deleteDatabaseCompletionHandlers.take(callbackID);
+ ASSERT(callback);
+ callback();
+}
+
} // namespace IDBServer
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -81,6 +81,7 @@
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 confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
WEBCORE_EXPORT void getAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID);
@@ -97,6 +98,7 @@
std::unique_ptr<IDBBackingStore> createBackingStore(const IDBDatabaseIdentifier&);
WEBCORE_EXPORT void closeAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point, std::function<void ()> completionHandler);
+ WEBCORE_EXPORT void closeAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>&, std::function<void ()> completionHandler);
private:
IDBServer(IDBBackingStoreTemporaryFileHandler&);
@@ -107,6 +109,10 @@
void performGetAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID);
void didGetAllDatabaseNames(uint64_t serverConnectionIdentifier, uint64_t callbackID, const Vector<String>& databaseNames);
+ void performCloseAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point, uint64_t callbackID);
+ void performCloseAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>&, uint64_t callbackID);
+ void didPerformCloseAndDeleteDatabases(uint64_t callbackID);
+
static void databaseThreadEntry(void*);
void databaseRunLoop();
void handleTaskRepliesOnMainThread();
@@ -125,6 +131,8 @@
HashMap<uint64_t, UniqueIDBDatabaseConnection*> m_databaseConnections;
HashMap<IDBResourceIdentifier, UniqueIDBDatabaseTransaction*> m_transactions;
+ HashMap<uint64_t, std::function<void ()>> m_deleteDatabaseCompletionHandlers;
+
String m_databaseDirectoryPath;
IDBBackingStoreTemporaryFileHandler& m_backingStoreTemporaryFileHandler;
};
Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -47,7 +47,7 @@
namespace WebCore {
namespace IDBServer {
-
+
UniqueIDBDatabase::UniqueIDBDatabase(IDBServer& server, const IDBDatabaseIdentifier& identifier)
: m_server(server)
, m_identifier(identifier)
@@ -63,7 +63,8 @@
ASSERT(!hasUnfinishedTransactions());
ASSERT(m_pendingTransactions.isEmpty());
ASSERT(m_openDatabaseConnections.isEmpty());
- ASSERT(m_closePendingDatabaseConnections.isEmpty());
+ ASSERT(m_clientClosePendingDatabaseConnections.isEmpty());
+ ASSERT(m_serverClosePendingDatabaseConnections.isEmpty());
}
const IDBDatabaseInfo& UniqueIDBDatabase::info() const
@@ -74,6 +75,9 @@
void UniqueIDBDatabase::openDatabaseConnection(IDBConnectionToClient& connection, const IDBRequestData& requestData)
{
+ LOG(IndexedDB, "UniqueIDBDatabase::openDatabaseConnection");
+ ASSERT(!m_hardClosedForUserDelete);
+
m_pendingOpenDBRequests.add(ServerOpenDBRequest::create(connection, requestData));
// An open operation is already in progress, so we can't possibly handle this one yet.
@@ -271,7 +275,7 @@
m_deleteBackingStoreInProgress = false;
- if (m_closePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty()) {
+ if (m_clientClosePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty()) {
m_server.closeUniqueIDBDatabase(*this);
return;
}
@@ -283,6 +287,7 @@
{
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDatabaseOperations - There are %u pending", m_pendingOpenDBRequests.size());
+ ASSERT(!m_hardClosedForUserDelete);
if (m_deleteBackingStoreInProgress)
return;
@@ -311,7 +316,7 @@
void UniqueIDBDatabase::handleCurrentOperation()
{
LOG(IndexedDB, "(main) UniqueIDBDatabase::handleCurrentOperation");
-
+ ASSERT(!m_hardClosedForUserDelete);
ASSERT(m_currentOpenDBRequest);
RefPtr<UniqueIDBDatabase> protectedThis(this);
@@ -339,32 +344,52 @@
return ++currentID;
}
-uint64_t UniqueIDBDatabase::storeCallback(ErrorCallback callback)
+uint64_t UniqueIDBDatabase::storeCallbackOrFireError(ErrorCallback callback)
{
+ if (m_hardClosedForUserDelete) {
+ callback(IDBError::userDeleteError());
+ return 0;
+ }
+
uint64_t identifier = generateUniqueCallbackIdentifier();
ASSERT(!m_errorCallbacks.contains(identifier));
m_errorCallbacks.add(identifier, callback);
return identifier;
}
-uint64_t UniqueIDBDatabase::storeCallback(KeyDataCallback callback)
+uint64_t UniqueIDBDatabase::storeCallbackOrFireError(KeyDataCallback callback)
{
+ if (m_hardClosedForUserDelete) {
+ callback(IDBError::userDeleteError(), { });
+ return 0;
+ }
+
uint64_t identifier = generateUniqueCallbackIdentifier();
ASSERT(!m_keyDataCallbacks.contains(identifier));
m_keyDataCallbacks.add(identifier, callback);
return identifier;
}
-uint64_t UniqueIDBDatabase::storeCallback(GetResultCallback callback)
+uint64_t UniqueIDBDatabase::storeCallbackOrFireError(GetResultCallback callback)
{
+ if (m_hardClosedForUserDelete) {
+ callback(IDBError::userDeleteError(), { });
+ return 0;
+ }
+
uint64_t identifier = generateUniqueCallbackIdentifier();
ASSERT(!m_getResultCallbacks.contains(identifier));
m_getResultCallbacks.add(identifier, callback);
return identifier;
}
-uint64_t UniqueIDBDatabase::storeCallback(CountCallback callback)
+uint64_t UniqueIDBDatabase::storeCallbackOrFireError(CountCallback callback)
{
+ if (m_hardClosedForUserDelete) {
+ callback(IDBError::userDeleteError(), 0);
+ return 0;
+ }
+
uint64_t identifier = generateUniqueCallbackIdentifier();
ASSERT(!m_countCallbacks.contains(identifier));
m_countCallbacks.add(identifier, callback);
@@ -374,6 +399,7 @@
void UniqueIDBDatabase::handleDelete(IDBConnectionToClient& connection, const IDBRequestData& requestData)
{
LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDelete");
+ ASSERT(!m_hardClosedForUserDelete);
m_pendingOpenDBRequests.add(ServerOpenDBRequest::create(connection, requestData));
handleDatabaseOperations();
@@ -538,7 +564,10 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::createObjectStore");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
+
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateObjectStore, callbackID, transaction.info().identifier(), info));
}
@@ -570,7 +599,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteObjectStore");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
auto* info = m_databaseInfo->infoForExistingObjectStore(objectStoreName);
if (!info) {
@@ -609,7 +640,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::clearObjectStore");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performClearObjectStore, callbackID, transaction.info().identifier(), objectStoreIdentifier));
}
@@ -638,7 +671,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::createIndex");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateIndex, callbackID, transaction.info().identifier(), info));
}
@@ -673,7 +708,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteIndex");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
if (!objectStoreInfo) {
@@ -721,7 +758,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::putOrAdd");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, value, overwriteMode));
}
@@ -857,7 +896,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::getRecord");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
if (uint64_t indexIdentifier = requestData.indexIdentifier())
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetIndexRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), indexIdentifier, requestData.indexRecordType(), range));
@@ -904,7 +945,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::getCount");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetCount, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), requestData.indexIdentifier(), range));
}
@@ -935,7 +978,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteRecord");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performDeleteRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyRangeData));
}
@@ -962,7 +1007,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::openCursor");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performOpenCursor, callbackID, requestData.transactionIdentifier(), info));
}
@@ -990,7 +1037,9 @@
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::iterateCursor");
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performIterateCursor, callbackID, requestData.transactionIdentifier(), requestData.cursorIdentifier(), key, count));
}
@@ -1032,7 +1081,9 @@
ASSERT(&transaction.databaseConnection().database() == this);
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
if (!prepareToFinishTransaction(transaction)) {
if (!m_openDatabaseConnections.contains(&transaction.databaseConnection())) {
@@ -1074,7 +1125,9 @@
ASSERT(&transaction.databaseConnection().database() == this);
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
if (!prepareToFinishTransaction(transaction)) {
if (!m_openDatabaseConnections.contains(&transaction.databaseConnection())) {
@@ -1149,7 +1202,7 @@
if (m_versionChangeDatabaseConnection == &connection) {
if (m_versionChangeTransaction) {
- m_closePendingDatabaseConnections.add(WTFMove(m_versionChangeDatabaseConnection));
+ m_clientClosePendingDatabaseConnections.add(WTFMove(m_versionChangeDatabaseConnection));
auto transactionIdentifier = m_versionChangeTransaction->info().identifier();
if (m_inProgressTransactions.contains(transactionIdentifier)) {
@@ -1177,7 +1230,7 @@
notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent(connection.identifier());
if (connection.hasNonFinishedTransactions()) {
- m_closePendingDatabaseConnections.add(WTFMove(protectedConnection));
+ m_clientClosePendingDatabaseConnections.add(WTFMove(protectedConnection));
return;
}
@@ -1185,9 +1238,38 @@
invokeOperationAndTransactionTimer();
}
+void UniqueIDBDatabase::connectionClosedFromServer(UniqueIDBDatabaseConnection& connection)
+{
+ ASSERT(isMainThread());
+ LOG(IndexedDB, "UniqueIDBDatabase::connectionClosedFromServer - %s (%" PRIu64 ")", connection.openRequestIdentifier().loggingString().utf8().data(), connection.identifier());
+
+ if (m_clientClosePendingDatabaseConnections.contains(&connection)) {
+ ASSERT(!m_openDatabaseConnections.contains(&connection));
+ ASSERT(!m_serverClosePendingDatabaseConnections.contains(&connection));
+ return;
+ }
+
+ Ref<UniqueIDBDatabaseConnection> protectedConnection(connection);
+ m_openDatabaseConnections.remove(&connection);
+
+ connection.connectionToClient().didCloseFromServer(connection, IDBError::userDeleteError());
+
+ m_serverClosePendingDatabaseConnections.add(WTFMove(protectedConnection));
+}
+
+void UniqueIDBDatabase::confirmDidCloseFromServer(UniqueIDBDatabaseConnection& connection)
+{
+ ASSERT(isMainThread());
+ LOG(IndexedDB, "UniqueIDBDatabase::confirmDidCloseFromServer - %s (%" PRIu64 ")", connection.openRequestIdentifier().loggingString().utf8().data(), connection.identifier());
+
+ ASSERT(m_serverClosePendingDatabaseConnections.contains(&connection));
+ m_serverClosePendingDatabaseConnections.remove(&connection);
+}
+
void UniqueIDBDatabase::enqueueTransaction(Ref<UniqueIDBDatabaseTransaction>&& transaction)
{
LOG(IndexedDB, "UniqueIDBDatabase::enqueueTransaction - %s", transaction->info().loggingString().utf8().data());
+ ASSERT(!m_hardClosedForUserDelete);
ASSERT(transaction->info().mode() != IndexedDB::TransactionMode::VersionChange);
@@ -1198,7 +1280,7 @@
bool UniqueIDBDatabase::isCurrentlyInUse() const
{
- return !m_openDatabaseConnections.isEmpty() || !m_closePendingDatabaseConnections.isEmpty() || !m_pendingOpenDBRequests.isEmpty() || m_currentOpenDBRequest || m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_isOpeningBackingStore || m_deleteBackingStoreInProgress;
+ return !m_openDatabaseConnections.isEmpty() || !m_clientClosePendingDatabaseConnections.isEmpty() || !m_pendingOpenDBRequests.isEmpty() || m_currentOpenDBRequest || m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_isOpeningBackingStore || m_deleteBackingStoreInProgress;
}
bool UniqueIDBDatabase::hasUnfinishedTransactions() const
@@ -1209,6 +1291,8 @@
void UniqueIDBDatabase::invokeOperationAndTransactionTimer()
{
LOG(IndexedDB, "UniqueIDBDatabase::invokeOperationAndTransactionTimer()");
+ ASSERT(!m_hardClosedForUserDelete);
+
if (!m_operationAndTransactionTimer.isActive())
m_operationAndTransactionTimer.startOneShot(0);
}
@@ -1216,6 +1300,7 @@
void UniqueIDBDatabase::operationAndTransactionTimerFired()
{
LOG(IndexedDB, "(main) UniqueIDBDatabase::operationAndTransactionTimerFired");
+ ASSERT(!m_hardClosedForUserDelete);
RefPtr<UniqueIDBDatabase> protectedThis(this);
@@ -1268,7 +1353,9 @@
refTransaction->didActivateInBackingStore(error);
};
- uint64_t callbackID = storeCallback(callback);
+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performActivateTransactionInBackingStore, callbackID, transaction.info()));
}
@@ -1373,26 +1460,28 @@
}
if (!transaction->databaseConnection().hasNonFinishedTransactions())
- m_closePendingDatabaseConnections.remove(&transaction->databaseConnection());
+ m_clientClosePendingDatabaseConnections.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) {
+ if (m_clientClosePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty() && !m_databaseInfo) {
m_server.closeUniqueIDBDatabase(*this);
return;
}
// Previously blocked operations might be runnable.
- invokeOperationAndTransactionTimer();
+ if (!m_hardClosedForUserDelete)
+ invokeOperationAndTransactionTimer();
}
void UniqueIDBDatabase::postDatabaseTask(std::unique_ptr<CrossThreadTask>&& task)
{
ASSERT(isMainThread());
m_databaseQueue.append(WTFMove(task));
+ ++m_queuedTaskCount;
m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::executeNextDatabaseTask));
}
@@ -1401,6 +1490,7 @@
{
ASSERT(!isMainThread());
m_databaseReplyQueue.append(WTFMove(task));
+ ++m_queuedTaskCount;
m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::executeNextDatabaseTaskReply));
}
@@ -1408,49 +1498,147 @@
void UniqueIDBDatabase::executeNextDatabaseTask()
{
ASSERT(!isMainThread());
+ ASSERT(m_queuedTaskCount);
auto task = m_databaseQueue.tryGetMessage();
ASSERT(task);
task->performTask();
+ --m_queuedTaskCount;
}
void UniqueIDBDatabase::executeNextDatabaseTaskReply()
{
ASSERT(isMainThread());
+ ASSERT(m_queuedTaskCount);
auto task = m_databaseReplyQueue.tryGetMessage();
ASSERT(task);
task->performTask();
+ --m_queuedTaskCount;
+
+ // If this database was force closed (e.g. for a user delete) and there are no more
+ // queued tasks left, delete this.
+ if (m_hardCloseProtector && doneWithHardClose())
+ m_hardCloseProtector = nullptr;
}
+bool UniqueIDBDatabase::doneWithHardClose()
+{
+ return (!m_queuedTaskCount && m_serverClosePendingDatabaseConnections.isEmpty());
+}
+
+static void errorOpenDBRequestForUserDelete(ServerOpenDBRequest& request)
+{
+ auto result = IDBResultData::error(request.requestData().requestIdentifier(), IDBError::userDeleteError());
+ if (request.isOpenRequest())
+ request.connection().didOpenDatabase(result);
+ else
+ request.connection().didDeleteDatabase(result);
+}
+
+void UniqueIDBDatabase::immediateCloseForUserDelete()
+{
+ LOG(IndexedDB, "UniqueIDBDatabase::immediateCloseForUserDelete - Cancelling (%i, %i, %i, %i) callbacks", m_errorCallbacks.size(), m_keyDataCallbacks.size(), m_getResultCallbacks.size(), m_countCallbacks.size());
+
+ // Error out all transactions
+ Vector<IDBResourceIdentifier> inProgressIdentifiers;
+ copyKeysToVector(m_inProgressTransactions, inProgressIdentifiers);
+ for (auto& identifier : inProgressIdentifiers)
+ m_inProgressTransactions.get(identifier)->abortWithoutCallback();
+
+ ASSERT(m_inProgressTransactions.isEmpty());
+
+ m_pendingTransactions.clear();
+ m_objectStoreTransactionCounts.clear();
+ m_objectStoreWriteTransactions.clear();
+
+ // Error out all pending callbacks
+ Vector<uint64_t> callbackIdentifiers;
+ IDBError error = IDBError::userDeleteError();
+ IDBKeyData keyData;
+ IDBGetResult getResult;
+
+ copyKeysToVector(m_errorCallbacks, callbackIdentifiers);
+ for (auto identifier : callbackIdentifiers)
+ performErrorCallback(identifier, error);
+
+ callbackIdentifiers.clear();
+ copyKeysToVector(m_keyDataCallbacks, callbackIdentifiers);
+ for (auto identifier : callbackIdentifiers)
+ performKeyDataCallback(identifier, error, keyData);
+
+ callbackIdentifiers.clear();
+ copyKeysToVector(m_getResultCallbacks, callbackIdentifiers);
+ for (auto identifier : callbackIdentifiers)
+ performGetResultCallback(identifier, error, getResult);
+
+ callbackIdentifiers.clear();
+ copyKeysToVector(m_countCallbacks, callbackIdentifiers);
+ for (auto identifier : callbackIdentifiers)
+ performCountCallback(identifier, error, 0);
+
+ // Error out all IDBOpenDBRequests
+ if (m_currentOpenDBRequest) {
+ errorOpenDBRequestForUserDelete(*m_currentOpenDBRequest);
+ m_currentOpenDBRequest = nullptr;
+ }
+
+ for (auto& request : m_pendingOpenDBRequests)
+ errorOpenDBRequestForUserDelete(*request);
+
+ m_pendingOpenDBRequests.clear();
+
+ // Close all open connections
+ ListHashSet<RefPtr<UniqueIDBDatabaseConnection>> openDatabaseConnections = m_openDatabaseConnections;
+ for (auto& connection : openDatabaseConnections)
+ connectionClosedFromServer(*connection);
+
+ // Cancel the operation timer
+ m_operationAndTransactionTimer.stop();
+
+ // Set up the database to remain alive-but-inert until all of its background activity finishes and all
+ // database connections confirm that they have closed.
+ m_hardClosedForUserDelete = true;
+ if (!doneWithHardClose())
+ m_hardCloseProtector = this;
+
+ // Remove the database from the IDBServer's set of open databases.
+ // If there is no in-progress background thread activity for this database, it will be deleted here.
+ m_server.closeUniqueIDBDatabase(*this);
+}
+
void UniqueIDBDatabase::performErrorCallback(uint64_t callbackIdentifier, const IDBError& error)
{
auto callback = m_errorCallbacks.take(callbackIdentifier);
- ASSERT(callback);
- callback(error);
+ ASSERT(callback || m_hardClosedForUserDelete);
+ if (callback)
+ callback(error);
}
void UniqueIDBDatabase::performKeyDataCallback(uint64_t callbackIdentifier, const IDBError& error, const IDBKeyData& resultKey)
{
auto callback = m_keyDataCallbacks.take(callbackIdentifier);
- ASSERT(callback);
- callback(error, resultKey);
+ ASSERT(callback || m_hardClosedForUserDelete);
+ if (callback)
+ callback(error, resultKey);
}
void UniqueIDBDatabase::performGetResultCallback(uint64_t callbackIdentifier, const IDBError& error, const IDBGetResult& resultData)
{
auto callback = m_getResultCallbacks.take(callbackIdentifier);
- ASSERT(callback);
- callback(error, resultData);
+ ASSERT(callback || m_hardClosedForUserDelete);
+ if (callback)
+ callback(error, resultData);
}
void UniqueIDBDatabase::performCountCallback(uint64_t callbackIdentifier, const IDBError& error, uint64_t count)
{
auto callback = m_countCallbacks.take(callbackIdentifier);
- ASSERT(callback);
- callback(error, count);
+ ASSERT(callback || m_hardClosedForUserDelete);
+ if (callback)
+ callback(error, count);
}
void UniqueIDBDatabase::forgetErrorCallback(uint64_t callbackIdentifier)
Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -101,12 +101,15 @@
void didFinishHandlingVersionChange(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& transactionIdentifier);
void transactionDestroyed(UniqueIDBDatabaseTransaction&);
void connectionClosedFromClient(UniqueIDBDatabaseConnection&);
+ void confirmConnectionClosedOnServer(UniqueIDBDatabaseConnection&);
void didFireVersionChangeEvent(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier);
void openDBRequestCancelled(const IDBResourceIdentifier& requestIdentifier);
+ void confirmDidCloseFromServer(UniqueIDBDatabaseConnection&);
void enqueueTransaction(Ref<UniqueIDBDatabaseTransaction>&&);
void handleDelete(IDBConnectionToClient&, const IDBRequestData&);
+ void immediateCloseForUserDelete();
static JSC::VM& databaseThreadVM();
static JSC::ExecState& databaseThreadExecState();
@@ -129,6 +132,8 @@
void activateTransactionInBackingStore(UniqueIDBDatabaseTransaction&);
void transactionCompleted(RefPtr<UniqueIDBDatabaseTransaction>&&);
+ void connectionClosedFromServer(UniqueIDBDatabaseConnection&);
+
// Database thread operations
void deleteBackingStore(const IDBDatabaseIdentifier&);
void openBackingStore(const IDBDatabaseIdentifier&);
@@ -167,10 +172,10 @@
void didPerformAbortTransaction(uint64_t callbackIdentifier, const IDBError&, const IDBResourceIdentifier& transactionIdentifier);
void didPerformActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBError&);
- uint64_t storeCallback(ErrorCallback);
- uint64_t storeCallback(KeyDataCallback);
- uint64_t storeCallback(GetResultCallback);
- uint64_t storeCallback(CountCallback);
+ uint64_t storeCallbackOrFireError(ErrorCallback);
+ uint64_t storeCallbackOrFireError(KeyDataCallback);
+ uint64_t storeCallbackOrFireError(GetResultCallback);
+ uint64_t storeCallbackOrFireError(CountCallback);
void performErrorCallback(uint64_t callbackIdentifier, const IDBError&);
void performKeyDataCallback(uint64_t callbackIdentifier, const IDBError&, const IDBKeyData&);
@@ -194,6 +199,8 @@
void executeNextDatabaseTask();
void executeNextDatabaseTaskReply();
+ bool doneWithHardClose();
+
IDBServer& m_server;
IDBDatabaseIdentifier m_identifier;
@@ -201,7 +208,8 @@
RefPtr<ServerOpenDBRequest> m_currentOpenDBRequest;
ListHashSet<RefPtr<UniqueIDBDatabaseConnection>> m_openDatabaseConnections;
- HashSet<RefPtr<UniqueIDBDatabaseConnection>> m_closePendingDatabaseConnections;
+ HashSet<RefPtr<UniqueIDBDatabaseConnection>> m_clientClosePendingDatabaseConnections;
+ HashSet<RefPtr<UniqueIDBDatabaseConnection>> m_serverClosePendingDatabaseConnections;
RefPtr<UniqueIDBDatabaseConnection> m_versionChangeDatabaseConnection;
RefPtr<UniqueIDBDatabaseTransaction> m_versionChangeTransaction;
@@ -235,6 +243,10 @@
MessageQueue<CrossThreadTask> m_databaseQueue;
MessageQueue<CrossThreadTask> m_databaseReplyQueue;
+ std::atomic<uint64_t> m_queuedTaskCount { 0 };
+
+ bool m_hardClosedForUserDelete { false };
+ RefPtr<UniqueIDBDatabase> m_hardCloseProtector;
};
} // namespace IDBServer
Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -89,6 +89,13 @@
m_database.connectionClosedFromClient(*this);
}
+void UniqueIDBDatabaseConnection::confirmDidCloseFromServer()
+{
+ LOG(IndexedDB, "UniqueIDBDatabaseConnection::confirmDidCloseFromServer - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
+
+ m_database.confirmDidCloseFromServer(*this);
+}
+
void UniqueIDBDatabaseConnection::didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier)
{
LOG(IndexedDB, "UniqueIDBDatabaseConnection::didFireVersionChangeEvent - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -74,6 +74,7 @@
void didDeleteIndex(const IDBResultData&);
void didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier);
void didFinishHandlingVersionChange(const IDBResourceIdentifier& transactionIdentifier);
+ void confirmDidCloseFromServer();
void abortTransactionWithoutCallback(UniqueIDBDatabaseTransaction&);
Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -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
@@ -65,6 +65,11 @@
return IDBDatabaseException::getErrorDescription(m_code);
}
+RefPtr<DOMError> IDBError::toDOMError() const
+{
+ return DOMError::create(IDBDatabaseException::getErrorName(m_code), m_message);
+}
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -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,11 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef IDBError_h
-#define IDBError_h
+#pragma once
#if ENABLE(INDEXED_DATABASE)
+#include "DOMError.h"
#include "IDBDatabaseException.h"
#include <wtf/text/WTFString.h>
@@ -39,8 +39,15 @@
IDBError(ExceptionCode);
IDBError(ExceptionCode, const String& message);
+ static IDBError userDeleteError()
+ {
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Database deleted by request of the user") };
+ }
+
IDBError& operator=(const IDBError&);
+ RefPtr<DOMError> toDOMError() const;
+
ExceptionCode code() const { return m_code; }
String name() const;
String message() const;
@@ -78,4 +85,3 @@
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
-#endif // IDBError_h
Modified: trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -367,6 +367,15 @@
});
}
+void InProcessIDBServer::didCloseFromServer(IDBServer::UniqueIDBDatabaseConnection& connection, const IDBError& error)
+{
+ RefPtr<InProcessIDBServer> protectedThis(this);
+ uint64_t databaseConnectionIdentifier = connection.identifier();
+ RunLoop::current().dispatch([this, protectedThis, databaseConnectionIdentifier, error] {
+ m_connectionToServer->didCloseFromServer(databaseConnectionIdentifier, error);
+ });
+}
+
void InProcessIDBServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
{
RefPtr<InProcessIDBServer> protectedThis(this);
@@ -407,6 +416,14 @@
});
}
+void InProcessIDBServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
+{
+ RefPtr<InProcessIDBServer> protectedThis(this);
+ RunLoop::current().dispatch([this, protectedThis, databaseConnectionIdentifier] {
+ m_server->confirmDidCloseFromServer(databaseConnectionIdentifier);
+ });
+}
+
void InProcessIDBServer::getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
{
RefPtr<InProcessIDBServer> protectedThis(this);
Modified: trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h (201097 => 201098)
--- trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -52,6 +52,7 @@
WEBCORE_EXPORT IDBClient::IDBConnectionToServer& connectionToServer() const;
IDBServer::IDBConnectionToClient& connectionToClient() const;
+ IDBServer::IDBServer& server() { return m_server.get(); }
IDBServer::IDBServer& idbServer() { return m_server.get(); }
@@ -77,6 +78,7 @@
void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier) final;
void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier) final;
void openDBRequestCancelled(const IDBRequestData&) final;
+ void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier) final;
void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) final;
// IDBConnectionToClient
@@ -98,6 +100,7 @@
void didIterateCursor(const IDBResultData&) final;
void fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion) final;
void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) final;
+ void didCloseFromServer(IDBServer::UniqueIDBDatabaseConnection&, const IDBError&) final;
void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) final;
void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) final;
Modified: trunk/Source/WebCore/platform/CrossThreadCopier.cpp (201097 => 201098)
--- trunk/Source/WebCore/platform/CrossThreadCopier.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/platform/CrossThreadCopier.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -85,6 +85,11 @@
return ThreadSafeDataBuffer(buffer);
}
+CrossThreadCopierBase<false, false, std::chrono::system_clock::time_point>::Type CrossThreadCopierBase<false, false, std::chrono::system_clock::time_point>::copy(const std::chrono::system_clock::time_point& timePoint)
+{
+ return timePoint;
+}
+
// Test CrossThreadCopier using COMPILE_ASSERT.
// Verify that ThreadSafeRefCounted objects get handled correctly.
Modified: trunk/Source/WebCore/platform/CrossThreadCopier.h (201097 => 201098)
--- trunk/Source/WebCore/platform/CrossThreadCopier.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebCore/platform/CrossThreadCopier.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -160,6 +160,11 @@
static Type copy(const ThreadSafeDataBuffer&);
};
+template<> struct CrossThreadCopierBase<false, false, std::chrono::system_clock::time_point> {
+ typedef std::chrono::system_clock::time_point Type;
+ static Type copy(const Type& source);
+};
+
template<typename T>
struct CrossThreadCopier : public CrossThreadCopierBase<CrossThreadCopierBaseHelper::IsEnumOrConvertibleToInteger<T>::value, CrossThreadCopierBaseHelper::IsThreadSafeRefCountedPointer<T>::value, T> {
};
Modified: trunk/Source/WebKit2/ChangeLog (201097 => 201098)
--- trunk/Source/WebKit2/ChangeLog 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebKit2/ChangeLog 2016-05-18 20:42:20 UTC (rev 201098)
@@ -1,5 +1,32 @@
2016-05-18 Brady Eidson <beid...@apple.com>
+ Modern IDB: Add support for server side closing of open database connections.
+ https://bugs.webkit.org/show_bug.cgi?id=157843
+
+ Reviewed by Alex Christensen.
+
+ - Implement the required IDB delegate code.
+ - Make DatabaseProcess::deleteWebsiteData call the right method in IDB server.
+
+ * DatabaseProcess/DatabaseProcess.cpp:
+ (WebKit::DatabaseProcess::deleteWebsiteData):
+
+ * DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp:
+ (WebKit::WebIDBConnectionToClient::didGetRecord):
+ (WebKit::WebIDBConnectionToClient::didCloseFromServer):
+ (WebKit::WebIDBConnectionToClient::confirmDidCloseFromServer):
+ * DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h:
+ * DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in:
+
+ * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
+ (WebKit::WebIDBConnectionToServer::confirmDidCloseFromServer):
+ (WebKit::WebIDBConnectionToServer::didStartTransaction):
+ (WebKit::WebIDBConnectionToServer::didCloseFromServer):
+ * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h:
+ * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in:
+
+2016-05-18 Brady Eidson <beid...@apple.com>
+
Modern IDB: Make TestRunner.clearAllDatabases also delete IndexedDB databases (once doing so is supported).
https://bugs.webkit.org/show_bug.cgi?id=157823
Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp (201097 => 201098)
--- trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014, 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
@@ -259,13 +259,8 @@
}));
#if ENABLE(INDEXED_DATABASE)
- if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
- postDatabaseTask(std::make_unique<CrossThreadTask>([this, callbackAggregator, modifiedSince] {
-
- deleteIndexedDatabaseEntriesModifiedSince(modifiedSince);
- RunLoop::main().dispatch([callbackAggregator] { });
- }));
- }
+ if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases))
+ m_idbServer->closeAndDeleteDatabasesModifiedSince(modifiedSince, [callbackAggregator] { });
#endif
}
Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp (201097 => 201098)
--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -127,6 +127,11 @@
void WebIDBConnectionToClient::didGetRecord(const WebCore::IDBResultData& resultData)
{
+ if (resultData.type() == IDBResultType::Error) {
+ send(Messages::WebIDBConnectionToServer::DidGetRecord(resultData));
+ return;
+ }
+
auto& blobFilePaths = resultData.getResult().value().blobFilePaths();
if (blobFilePaths.isEmpty()) {
send(Messages::WebIDBConnectionToServer::DidGetRecord(resultData));
@@ -169,6 +174,11 @@
send(Messages::WebIDBConnectionToServer::DidStartTransaction(transactionIdentifier, error));
}
+void WebIDBConnectionToClient::didCloseFromServer(WebCore::IDBServer::UniqueIDBDatabaseConnection& connection, const WebCore::IDBError& error)
+{
+ send(Messages::WebIDBConnectionToServer::DidCloseFromServer(connection.identifier(), error));
+}
+
void WebIDBConnectionToClient::notifyOpenDBRequestBlocked(const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
{
send(Messages::WebIDBConnectionToServer::NotifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion));
@@ -294,6 +304,11 @@
DatabaseProcess::singleton().idbServer().openDBRequestCancelled(requestData);
}
+void WebIDBConnectionToClient::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
+{
+ DatabaseProcess::singleton().idbServer().confirmDidCloseFromServer(databaseConnectionIdentifier);
+}
+
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);
Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h (201097 => 201098)
--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -23,8 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebIDBConnectionToClient_h
-#define WebIDBConnectionToClient_h
+#pragma once
#if ENABLE(INDEXED_DATABASE)
@@ -76,6 +75,7 @@
void fireVersionChangeEvent(WebCore::IDBServer::UniqueIDBDatabaseConnection&, const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion) final;
void didStartTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier, const WebCore::IDBError&) final;
+ void didCloseFromServer(WebCore::IDBServer::UniqueIDBDatabaseConnection&, const WebCore::IDBError&) final;
void notifyOpenDBRequestBlocked(const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) final;
void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) final;
@@ -106,6 +106,7 @@
void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier);
void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier);
void openDBRequestCancelled(const WebCore::IDBRequestData&);
+ void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
void getAllDatabaseNames(uint64_t serverConnectionIdentifier, const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID);
@@ -127,4 +128,3 @@
} // namespace WebKit
#endif // ENABLE(INDEXED_DATABASE)
-#endif // WebIDBConnectionToClient_h
Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in (201097 => 201098)
--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in 2016-05-18 20:42:20 UTC (rev 201098)
@@ -45,6 +45,7 @@
AbortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier transactionIdentifier);
DidFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier requestIdentifier);
OpenDBRequestCancelled(WebCore::IDBRequestData requestData);
+ ConfirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
GetAllDatabaseNames(uint64_t serverConnectionIdentifier, struct WebCore::SecurityOriginData topOrigin, struct WebCore::SecurityOriginData openingOrigin, uint64_t callbackID);
}
Modified: trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp (201097 => 201098)
--- trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp 2016-05-18 20:42:20 UTC (rev 201098)
@@ -186,6 +186,11 @@
send(Messages::WebIDBConnectionToClient::OpenDBRequestCancelled(requestData));
}
+void WebIDBConnectionToServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
+{
+ send(Messages::WebIDBConnectionToClient::ConfirmDidCloseFromServer(databaseConnectionIdentifier));
+}
+
void WebIDBConnectionToServer::getAllDatabaseNames(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID)
{
send(Messages::WebIDBConnectionToClient::GetAllDatabaseNames(m_identifier, topOrigin, openingOrigin, callbackID));
@@ -282,11 +287,16 @@
m_connectionToServer->fireVersionChangeEvent(uniqueDatabaseConnectionIdentifier, requestIdentifier, requestedVersion);
}
-void WebIDBConnectionToServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const WebCore::IDBError& error)
+void WebIDBConnectionToServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
{
m_connectionToServer->didStartTransaction(transactionIdentifier, error);
}
+void WebIDBConnectionToServer::didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError& error)
+{
+ m_connectionToServer->didCloseFromServer(databaseConnectionIdentifier, error);
+}
+
void WebIDBConnectionToServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
{
m_connectionToServer->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
Modified: trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h (201097 => 201098)
--- trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h 2016-05-18 20:42:20 UTC (rev 201098)
@@ -23,8 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebIDBConnectionToServer_h
-#define WebIDBConnectionToServer_h
+#pragma once
#if ENABLE(INDEXED_DATABASE)
@@ -66,6 +65,7 @@
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 confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier) final;
void getAllDatabaseNames(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID) final;
@@ -91,6 +91,7 @@
void didIterateCursor(const WebCore::IDBResultData&);
void fireVersionChangeEvent(uint64_t uniqueDatabaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
void didStartTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier, const WebCore::IDBError&);
+ void didCloseFromServer(uint64_t databaseConnectionIdentifier, const WebCore::IDBError&);
void notifyOpenDBRequestBlocked(const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames);
@@ -109,4 +110,3 @@
} // namespace WebKit
#endif // ENABLE(INDEXED_DATABASE)
-#endif // WebIDBConnectionToServer_h
Modified: trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in (201097 => 201098)
--- trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in 2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in 2016-05-18 20:42:20 UTC (rev 201098)
@@ -42,6 +42,7 @@
FireVersionChangeEvent(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier requestIdentifier, uint64_t requestedVersion)
DidStartTransaction(WebCore::IDBResourceIdentifier transactionIdentifier, WebCore::IDBError error)
+ DidCloseFromServer(uint64_t databaseConnectionIdentifier, WebCore::IDBError error) final;
NotifyOpenDBRequestBlocked(WebCore::IDBResourceIdentifier requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
DidGetAllDatabaseNames(uint64_t callbackID, Vector<String> databaseNames)