<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[201098] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/201098">201098</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2016-05-18 13:42:20 -0700 (Wed, 18 May 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>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.
Source/WebCore:
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:
Source/WebKit2:
- 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:
LayoutTests:
* 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.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBDatabasecpp">trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBDatabaseh">trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBDatabaseIdentifierh">trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseIdentifier.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBTransactioncpp">trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBTransactionh">trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBConnectionProxycpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBConnectionProxyh">trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServercpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServerh">trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServerDelegateh">trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClientcpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClienth">trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClientDelegateh">trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBServercpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBServerh">trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseConnectioncpp">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseConnectionh">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBErrorcpp">trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBErrorh">trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedInProcessIDBServercpp">trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedInProcessIDBServerh">trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformCrossThreadCopiercpp">trunk/Source/WebCore/platform/CrossThreadCopier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformCrossThreadCopierh">trunk/Source/WebCore/platform/CrossThreadCopier.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessDatabaseProcesscpp">trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessIndexedDBWebIDBConnectionToClientcpp">trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessIndexedDBWebIDBConnectionToClienth">trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessIndexedDBWebIDBConnectionToClientmessagesin">trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessDatabasesIndexedDBWebIDBConnectionToServercpp">trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessDatabasesIndexedDBWebIDBConnectionToServerh">trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessDatabasesIndexedDBWebIDBConnectionToServermessagesin">trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernhandleuserdeleteexpectedtxt">trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernhandleuserdeletehtml">trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete.html</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernresourceshandleuserdeletejs">trunk/LayoutTests/storage/indexeddb/modern/resources/handle-user-delete.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-05-18 20:21:31 UTC (rev 201097)
+++ trunk/LayoutTests/ChangeLog        2016-05-18 20:42:20 UTC (rev 201098)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-05-18 Brady Eidson <beidson@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.
+
</ins><span class="cx"> 2016-05-18 Myles C. Maxfield <mmaxfield@apple.com>
</span><span class="cx">
</span><span class="cx"> [OS X] Update platform/mac/fast/text/sticky-typesetting-features.html
</span></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernhandleuserdeleteexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete-expected.txt (0 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+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
+
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernhandleuserdeletehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/handle-user-delete.html (0 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../resources/shared.js"></script>
+</head>
+<body>
+
+<script src="resources/handle-user-delete.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernresourceshandleuserdeletejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/resources/handle-user-delete.js (0 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+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();
+ }
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,136 @@
</span><ins>+2016-05-18 Brady Eidson <beidson@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:
+
</ins><span class="cx"> 2016-05-18 Simon Fraser <simon.fraser@apple.com>
</span><span class="cx">
</span><span class="cx"> REGRESSION (r200534) Command-+ no longer zooms pages
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -245,6 +245,25 @@
</span><span class="cx"> maybeCloseInServer();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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);
+}
+
</ins><span class="cx"> void IDBDatabase::maybeCloseInServer()
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBDatabase::maybeCloseInServer - %" PRIu64, m_databaseConnectionIdentifier);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -86,6 +86,7 @@
</span><span class="cx"> void didAbortTransaction(IDBTransaction&);
</span><span class="cx">
</span><span class="cx"> void fireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
</span><ins>+ void didCloseFromServer(const IDBError&);
</ins><span class="cx">
</span><span class="cx"> IDBClient::IDBConnectionProxy& connectionProxy() { return m_connectionProxy.get(); }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBDatabaseIdentifierh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseIdentifier.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -102,6 +102,11 @@
</span><span class="cx"> String debugString() const;
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+ bool isRelatedToOrigin(const SecurityOriginData& other) const
+ {
+ return m_openingOrigin == other || m_mainFrameOrigin == other;
+ }
+
</ins><span class="cx"> private:
</span><span class="cx"> String m_databaseName;
</span><span class="cx"> SecurityOriginData m_openingOrigin;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBTransactioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1075,6 +1075,29 @@
</span><span class="cx"> return m_database->originThreadID();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBTransactionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -145,6 +145,8 @@
</span><span class="cx">
</span><span class="cx"> ThreadIdentifier originThreadID() const;
</span><span class="cx">
</span><ins>+ void connectionClosedFromServer(const IDBError&);
+
</ins><span class="cx"> private:
</span><span class="cx"> IDBTransaction(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest*);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBConnectionProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -249,7 +249,8 @@
</span><span class="cx"> operation = m_activeOperations.take(resultData.requestIdentifier());
</span><span class="cx"> }
</span><span class="cx">
</span><del>- ASSERT(operation);
</del><ins>+ if (!operation)
+ return;
</ins><span class="cx">
</span><span class="cx"> performCallbackOnCorrectThread(*operation, &TransactionOperation::completed, resultData);
</span><span class="cx"> }
</span><span class="lines">@@ -388,6 +389,29 @@
</span><span class="cx"> callConnectionOnMainThread(&IDBConnectionToServer::databaseConnectionClosed, database.databaseConnectionIdentifier());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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());
+}
+
</ins><span class="cx"> void IDBConnectionProxy::scheduleMainThreadTasks()
</span><span class="cx"> {
</span><span class="cx"> Locker<Lock> locker(m_mainThreadTaskLock);
</span><span class="lines">@@ -438,6 +462,14 @@
</span><span class="cx"> m_databaseConnectionMap.remove(database.databaseConnectionIdentifier());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void IDBConnectionProxy::forgetActiveOperations(const Vector<RefPtr<TransactionOperation>>& operations)
+{
+ Locker<Lock> locker(m_transactionOperationLock);
+
+ for (auto& operation : operations)
+ m_activeOperations.remove(operation->identifier());
+}
+
</ins><span class="cx"> } // namesapce IDBClient
</span><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBConnectionProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -93,6 +93,9 @@
</span><span class="cx"> void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, IDBTransaction&);
</span><span class="cx"> void databaseConnectionClosed(IDBDatabase&);
</span><span class="cx">
</span><ins>+ void didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError&);
+ void confirmDidCloseFromServer(IDBDatabase&);
+
</ins><span class="cx"> void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier);
</span><span class="cx">
</span><span class="cx"> void completeOperation(const IDBResultData&);
</span><span class="lines">@@ -109,6 +112,8 @@
</span><span class="cx">
</span><span class="cx"> RefPtr<IDBOpenDBRequest> takeIDBOpenDBRequest(IDBOpenDBRequest&);
</span><span class="cx">
</span><ins>+ void forgetActiveOperations(const Vector<RefPtr<TransactionOperation>>&);
+
</ins><span class="cx"> private:
</span><span class="cx"> void completeOpenDBRequest(const IDBResultData&);
</span><span class="cx"> bool hasRecordOfTransaction(const IDBTransaction&) const;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -316,6 +316,22 @@
</span><span class="cx"> m_proxy->didStartTransaction(transactionIdentifier, error);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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);
+}
+
</ins><span class="cx"> void IDBConnectionToServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBConnectionToServer::didStartTransaction");
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -106,6 +106,10 @@
</span><span class="cx"> void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
</span><span class="cx">
</span><span class="cx"> WEBCORE_EXPORT void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
</span><ins>+
+ WEBCORE_EXPORT void didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError&);
+ void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
+
</ins><span class="cx"> WEBCORE_EXPORT void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
</span><span class="cx"> void openDBRequestCancelled(const IDBRequestData&);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServerDelegateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -77,6 +77,7 @@
</span><span class="cx"> virtual void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier) = 0;
</span><span class="cx"> virtual void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier) = 0;
</span><span class="cx"> virtual void openDBRequestCancelled(const IDBRequestData&) = 0;
</span><ins>+ virtual void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier) = 0;
</ins><span class="cx">
</span><span class="cx"> virtual void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) = 0;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -133,6 +133,11 @@
</span><span class="cx"> m_delegate->didStartTransaction(transactionIdentifier, error);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void IDBConnectionToClient::didCloseFromServer(UniqueIDBDatabaseConnection& connection, const IDBError& error)
+{
+ m_delegate->didCloseFromServer(connection, error);
+}
+
</ins><span class="cx"> void IDBConnectionToClient::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
</span><span class="cx"> {
</span><span class="cx"> m_delegate->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -66,6 +66,7 @@
</span><span class="cx">
</span><span class="cx"> void fireVersionChangeEvent(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
</span><span class="cx"> void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
</span><ins>+ void didCloseFromServer(UniqueIDBDatabaseConnection&, const IDBError&);
</ins><span class="cx">
</span><span class="cx"> void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClientDelegateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx">
</span><span class="cx"> virtual void fireVersionChangeEvent(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion) = 0;
</span><span class="cx"> virtual void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) = 0;
</span><ins>+ virtual void didCloseFromServer(UniqueIDBDatabaseConnection&, const IDBError&) = 0;
</ins><span class="cx"> virtual void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) = 0;
</span><span class="cx">
</span><span class="cx"> virtual void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) = 0;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -33,7 +33,9 @@
</span><span class="cx"> #include "IDBResultData.h"
</span><span class="cx"> #include "Logging.h"
</span><span class="cx"> #include "MemoryIDBBackingStore.h"
</span><ins>+#include "SQLiteFileSystem.h"
</ins><span class="cx"> #include "SQLiteIDBBackingStore.h"
</span><ins>+#include "SecurityOrigin.h"
</ins><span class="cx"> #include <wtf/Locker.h>
</span><span class="cx"> #include <wtf/MainThread.h>
</span><span class="cx">
</span><span class="lines">@@ -388,6 +390,14 @@
</span><span class="cx"> uniqueIDBDatabase->openDBRequestCancelled(requestData.requestIdentifier());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void IDBServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
+{
+ LOG(IndexedDB, "IDBServer::confirmDidCloseFromServer");
+
+ if (auto databaseConnection = m_databaseConnections.get(databaseConnectionIdentifier))
+ databaseConnection->confirmDidCloseFromServer();
+}
+
</ins><span class="cx"> void IDBServer::getAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
</span><span class="cx"> {
</span><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &IDBServer::performGetAllDatabaseNames, serverConnectionIdentifier, mainFrameOrigin, openingOrigin, callbackID));
</span><span class="lines">@@ -468,12 +478,77 @@
</span><span class="cx"> task->performTask();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void IDBServer::closeAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point, std::function<void ()> completionHandler)
</del><ins>+static uint64_t generateDeleteCallbackID()
</ins><span class="cx"> {
</span><del>- // FIXME: Implement (https://bugs.webkit.org/show_bug.cgi?id=157626)
- completionHandler();
</del><ins>+ ASSERT(isMainThread());
+ static uint64_t currentID = 0;
+ return ++currentID;
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+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();
+}
+
</ins><span class="cx"> } // namespace IDBServer
</span><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -81,6 +81,7 @@
</span><span class="cx"> WEBCORE_EXPORT void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier);
</span><span class="cx"> WEBCORE_EXPORT void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
</span><span class="cx"> WEBCORE_EXPORT void openDBRequestCancelled(const IDBRequestData&);
</span><ins>+ WEBCORE_EXPORT void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
</ins><span class="cx">
</span><span class="cx"> WEBCORE_EXPORT void getAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID);
</span><span class="cx">
</span><span class="lines">@@ -97,6 +98,7 @@
</span><span class="cx"> std::unique_ptr<IDBBackingStore> createBackingStore(const IDBDatabaseIdentifier&);
</span><span class="cx">
</span><span class="cx"> WEBCORE_EXPORT void closeAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point, std::function<void ()> completionHandler);
</span><ins>+ WEBCORE_EXPORT void closeAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>&, std::function<void ()> completionHandler);
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> IDBServer(IDBBackingStoreTemporaryFileHandler&);
</span><span class="lines">@@ -107,6 +109,10 @@
</span><span class="cx"> void performGetAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID);
</span><span class="cx"> void didGetAllDatabaseNames(uint64_t serverConnectionIdentifier, uint64_t callbackID, const Vector<String>& databaseNames);
</span><span class="cx">
</span><ins>+ void performCloseAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point, uint64_t callbackID);
+ void performCloseAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>&, uint64_t callbackID);
+ void didPerformCloseAndDeleteDatabases(uint64_t callbackID);
+
</ins><span class="cx"> static void databaseThreadEntry(void*);
</span><span class="cx"> void databaseRunLoop();
</span><span class="cx"> void handleTaskRepliesOnMainThread();
</span><span class="lines">@@ -125,6 +131,8 @@
</span><span class="cx"> HashMap<uint64_t, UniqueIDBDatabaseConnection*> m_databaseConnections;
</span><span class="cx"> HashMap<IDBResourceIdentifier, UniqueIDBDatabaseTransaction*> m_transactions;
</span><span class="cx">
</span><ins>+ HashMap<uint64_t, std::function<void ()>> m_deleteDatabaseCompletionHandlers;
+
</ins><span class="cx"> String m_databaseDirectoryPath;
</span><span class="cx"> IDBBackingStoreTemporaryFileHandler& m_backingStoreTemporaryFileHandler;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBServer {
</span><del>-
</del><ins>+
</ins><span class="cx"> UniqueIDBDatabase::UniqueIDBDatabase(IDBServer& server, const IDBDatabaseIdentifier& identifier)
</span><span class="cx"> : m_server(server)
</span><span class="cx"> , m_identifier(identifier)
</span><span class="lines">@@ -63,7 +63,8 @@
</span><span class="cx"> ASSERT(!hasUnfinishedTransactions());
</span><span class="cx"> ASSERT(m_pendingTransactions.isEmpty());
</span><span class="cx"> ASSERT(m_openDatabaseConnections.isEmpty());
</span><del>- ASSERT(m_closePendingDatabaseConnections.isEmpty());
</del><ins>+ ASSERT(m_clientClosePendingDatabaseConnections.isEmpty());
+ ASSERT(m_serverClosePendingDatabaseConnections.isEmpty());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> const IDBDatabaseInfo& UniqueIDBDatabase::info() const
</span><span class="lines">@@ -74,6 +75,9 @@
</span><span class="cx">
</span><span class="cx"> void UniqueIDBDatabase::openDatabaseConnection(IDBConnectionToClient& connection, const IDBRequestData& requestData)
</span><span class="cx"> {
</span><ins>+ LOG(IndexedDB, "UniqueIDBDatabase::openDatabaseConnection");
+ ASSERT(!m_hardClosedForUserDelete);
+
</ins><span class="cx"> m_pendingOpenDBRequests.add(ServerOpenDBRequest::create(connection, requestData));
</span><span class="cx">
</span><span class="cx"> // An open operation is already in progress, so we can't possibly handle this one yet.
</span><span class="lines">@@ -271,7 +275,7 @@
</span><span class="cx">
</span><span class="cx"> m_deleteBackingStoreInProgress = false;
</span><span class="cx">
</span><del>- if (m_closePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty()) {
</del><ins>+ if (m_clientClosePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty()) {
</ins><span class="cx"> m_server.closeUniqueIDBDatabase(*this);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -283,6 +287,7 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDatabaseOperations - There are %u pending", m_pendingOpenDBRequests.size());
</span><ins>+ ASSERT(!m_hardClosedForUserDelete);
</ins><span class="cx">
</span><span class="cx"> if (m_deleteBackingStoreInProgress)
</span><span class="cx"> return;
</span><span class="lines">@@ -311,7 +316,7 @@
</span><span class="cx"> void UniqueIDBDatabase::handleCurrentOperation()
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::handleCurrentOperation");
</span><del>-
</del><ins>+ ASSERT(!m_hardClosedForUserDelete);
</ins><span class="cx"> ASSERT(m_currentOpenDBRequest);
</span><span class="cx">
</span><span class="cx"> RefPtr<UniqueIDBDatabase> protectedThis(this);
</span><span class="lines">@@ -339,32 +344,52 @@
</span><span class="cx"> return ++currentID;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-uint64_t UniqueIDBDatabase::storeCallback(ErrorCallback callback)
</del><ins>+uint64_t UniqueIDBDatabase::storeCallbackOrFireError(ErrorCallback callback)
</ins><span class="cx"> {
</span><ins>+ if (m_hardClosedForUserDelete) {
+ callback(IDBError::userDeleteError());
+ return 0;
+ }
+
</ins><span class="cx"> uint64_t identifier = generateUniqueCallbackIdentifier();
</span><span class="cx"> ASSERT(!m_errorCallbacks.contains(identifier));
</span><span class="cx"> m_errorCallbacks.add(identifier, callback);
</span><span class="cx"> return identifier;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-uint64_t UniqueIDBDatabase::storeCallback(KeyDataCallback callback)
</del><ins>+uint64_t UniqueIDBDatabase::storeCallbackOrFireError(KeyDataCallback callback)
</ins><span class="cx"> {
</span><ins>+ if (m_hardClosedForUserDelete) {
+ callback(IDBError::userDeleteError(), { });
+ return 0;
+ }
+
</ins><span class="cx"> uint64_t identifier = generateUniqueCallbackIdentifier();
</span><span class="cx"> ASSERT(!m_keyDataCallbacks.contains(identifier));
</span><span class="cx"> m_keyDataCallbacks.add(identifier, callback);
</span><span class="cx"> return identifier;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-uint64_t UniqueIDBDatabase::storeCallback(GetResultCallback callback)
</del><ins>+uint64_t UniqueIDBDatabase::storeCallbackOrFireError(GetResultCallback callback)
</ins><span class="cx"> {
</span><ins>+ if (m_hardClosedForUserDelete) {
+ callback(IDBError::userDeleteError(), { });
+ return 0;
+ }
+
</ins><span class="cx"> uint64_t identifier = generateUniqueCallbackIdentifier();
</span><span class="cx"> ASSERT(!m_getResultCallbacks.contains(identifier));
</span><span class="cx"> m_getResultCallbacks.add(identifier, callback);
</span><span class="cx"> return identifier;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-uint64_t UniqueIDBDatabase::storeCallback(CountCallback callback)
</del><ins>+uint64_t UniqueIDBDatabase::storeCallbackOrFireError(CountCallback callback)
</ins><span class="cx"> {
</span><ins>+ if (m_hardClosedForUserDelete) {
+ callback(IDBError::userDeleteError(), 0);
+ return 0;
+ }
+
</ins><span class="cx"> uint64_t identifier = generateUniqueCallbackIdentifier();
</span><span class="cx"> ASSERT(!m_countCallbacks.contains(identifier));
</span><span class="cx"> m_countCallbacks.add(identifier, callback);
</span><span class="lines">@@ -374,6 +399,7 @@
</span><span class="cx"> void UniqueIDBDatabase::handleDelete(IDBConnectionToClient& connection, const IDBRequestData& requestData)
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDelete");
</span><ins>+ ASSERT(!m_hardClosedForUserDelete);
</ins><span class="cx">
</span><span class="cx"> m_pendingOpenDBRequests.add(ServerOpenDBRequest::create(connection, requestData));
</span><span class="cx"> handleDatabaseOperations();
</span><span class="lines">@@ -538,7 +564,10 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::createObjectStore");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
+
</ins><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateObjectStore, callbackID, transaction.info().identifier(), info));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -570,7 +599,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteObjectStore");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx">
</span><span class="cx"> auto* info = m_databaseInfo->infoForExistingObjectStore(objectStoreName);
</span><span class="cx"> if (!info) {
</span><span class="lines">@@ -609,7 +640,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::clearObjectStore");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performClearObjectStore, callbackID, transaction.info().identifier(), objectStoreIdentifier));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -638,7 +671,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::createIndex");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateIndex, callbackID, transaction.info().identifier(), info));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -673,7 +708,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteIndex");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx">
</span><span class="cx"> auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
</span><span class="cx"> if (!objectStoreInfo) {
</span><span class="lines">@@ -721,7 +758,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::putOrAdd");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, value, overwriteMode));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -857,7 +896,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::getRecord");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx">
</span><span class="cx"> if (uint64_t indexIdentifier = requestData.indexIdentifier())
</span><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetIndexRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), indexIdentifier, requestData.indexRecordType(), range));
</span><span class="lines">@@ -904,7 +945,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::getCount");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetCount, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), requestData.indexIdentifier(), range));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -935,7 +978,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteRecord");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performDeleteRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyRangeData));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -962,7 +1007,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::openCursor");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performOpenCursor, callbackID, requestData.transactionIdentifier(), info));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -990,7 +1037,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::iterateCursor");
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performIterateCursor, callbackID, requestData.transactionIdentifier(), requestData.cursorIdentifier(), key, count));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1032,7 +1081,9 @@
</span><span class="cx">
</span><span class="cx"> ASSERT(&transaction.databaseConnection().database() == this);
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx">
</span><span class="cx"> if (!prepareToFinishTransaction(transaction)) {
</span><span class="cx"> if (!m_openDatabaseConnections.contains(&transaction.databaseConnection())) {
</span><span class="lines">@@ -1074,7 +1125,9 @@
</span><span class="cx">
</span><span class="cx"> ASSERT(&transaction.databaseConnection().database() == this);
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx">
</span><span class="cx"> if (!prepareToFinishTransaction(transaction)) {
</span><span class="cx"> if (!m_openDatabaseConnections.contains(&transaction.databaseConnection())) {
</span><span class="lines">@@ -1149,7 +1202,7 @@
</span><span class="cx">
</span><span class="cx"> if (m_versionChangeDatabaseConnection == &connection) {
</span><span class="cx"> if (m_versionChangeTransaction) {
</span><del>- m_closePendingDatabaseConnections.add(WTFMove(m_versionChangeDatabaseConnection));
</del><ins>+ m_clientClosePendingDatabaseConnections.add(WTFMove(m_versionChangeDatabaseConnection));
</ins><span class="cx">
</span><span class="cx"> auto transactionIdentifier = m_versionChangeTransaction->info().identifier();
</span><span class="cx"> if (m_inProgressTransactions.contains(transactionIdentifier)) {
</span><span class="lines">@@ -1177,7 +1230,7 @@
</span><span class="cx"> notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent(connection.identifier());
</span><span class="cx">
</span><span class="cx"> if (connection.hasNonFinishedTransactions()) {
</span><del>- m_closePendingDatabaseConnections.add(WTFMove(protectedConnection));
</del><ins>+ m_clientClosePendingDatabaseConnections.add(WTFMove(protectedConnection));
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1185,9 +1238,38 @@
</span><span class="cx"> invokeOperationAndTransactionTimer();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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);
+}
+
</ins><span class="cx"> void UniqueIDBDatabase::enqueueTransaction(Ref<UniqueIDBDatabaseTransaction>&& transaction)
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "UniqueIDBDatabase::enqueueTransaction - %s", transaction->info().loggingString().utf8().data());
</span><ins>+ ASSERT(!m_hardClosedForUserDelete);
</ins><span class="cx">
</span><span class="cx"> ASSERT(transaction->info().mode() != IndexedDB::TransactionMode::VersionChange);
</span><span class="cx">
</span><span class="lines">@@ -1198,7 +1280,7 @@
</span><span class="cx">
</span><span class="cx"> bool UniqueIDBDatabase::isCurrentlyInUse() const
</span><span class="cx"> {
</span><del>- return !m_openDatabaseConnections.isEmpty() || !m_closePendingDatabaseConnections.isEmpty() || !m_pendingOpenDBRequests.isEmpty() || m_currentOpenDBRequest || m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_isOpeningBackingStore || m_deleteBackingStoreInProgress;
</del><ins>+ return !m_openDatabaseConnections.isEmpty() || !m_clientClosePendingDatabaseConnections.isEmpty() || !m_pendingOpenDBRequests.isEmpty() || m_currentOpenDBRequest || m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_isOpeningBackingStore || m_deleteBackingStoreInProgress;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool UniqueIDBDatabase::hasUnfinishedTransactions() const
</span><span class="lines">@@ -1209,6 +1291,8 @@
</span><span class="cx"> void UniqueIDBDatabase::invokeOperationAndTransactionTimer()
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "UniqueIDBDatabase::invokeOperationAndTransactionTimer()");
</span><ins>+ ASSERT(!m_hardClosedForUserDelete);
+
</ins><span class="cx"> if (!m_operationAndTransactionTimer.isActive())
</span><span class="cx"> m_operationAndTransactionTimer.startOneShot(0);
</span><span class="cx"> }
</span><span class="lines">@@ -1216,6 +1300,7 @@
</span><span class="cx"> void UniqueIDBDatabase::operationAndTransactionTimerFired()
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "(main) UniqueIDBDatabase::operationAndTransactionTimerFired");
</span><ins>+ ASSERT(!m_hardClosedForUserDelete);
</ins><span class="cx">
</span><span class="cx"> RefPtr<UniqueIDBDatabase> protectedThis(this);
</span><span class="cx">
</span><span class="lines">@@ -1268,7 +1353,9 @@
</span><span class="cx"> refTransaction->didActivateInBackingStore(error);
</span><span class="cx"> };
</span><span class="cx">
</span><del>- uint64_t callbackID = storeCallback(callback);
</del><ins>+ uint64_t callbackID = storeCallbackOrFireError(callback);
+ if (!callbackID)
+ return;
</ins><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performActivateTransactionInBackingStore, callbackID, transaction.info()));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1373,26 +1460,28 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (!transaction->databaseConnection().hasNonFinishedTransactions())
</span><del>- m_closePendingDatabaseConnections.remove(&transaction->databaseConnection());
</del><ins>+ m_clientClosePendingDatabaseConnections.remove(&transaction->databaseConnection());
</ins><span class="cx">
</span><span class="cx"> if (m_versionChangeTransaction == transaction)
</span><span class="cx"> m_versionChangeTransaction = nullptr;
</span><span class="cx">
</span><span class="cx"> // It's possible that this database had its backing store deleted but there were a few outstanding asynchronous operations.
</span><span class="cx"> // If this transaction completing was the last of those operations, we can finally delete this UniqueIDBDatabase.
</span><del>- if (m_closePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty() && !m_databaseInfo) {
</del><ins>+ if (m_clientClosePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty() && !m_databaseInfo) {
</ins><span class="cx"> m_server.closeUniqueIDBDatabase(*this);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Previously blocked operations might be runnable.
</span><del>- invokeOperationAndTransactionTimer();
</del><ins>+ if (!m_hardClosedForUserDelete)
+ invokeOperationAndTransactionTimer();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void UniqueIDBDatabase::postDatabaseTask(std::unique_ptr<CrossThreadTask>&& task)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> m_databaseQueue.append(WTFMove(task));
</span><ins>+ ++m_queuedTaskCount;
</ins><span class="cx">
</span><span class="cx"> m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::executeNextDatabaseTask));
</span><span class="cx"> }
</span><span class="lines">@@ -1401,6 +1490,7 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!isMainThread());
</span><span class="cx"> m_databaseReplyQueue.append(WTFMove(task));
</span><ins>+ ++m_queuedTaskCount;
</ins><span class="cx">
</span><span class="cx"> m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::executeNextDatabaseTaskReply));
</span><span class="cx"> }
</span><span class="lines">@@ -1408,49 +1498,147 @@
</span><span class="cx"> void UniqueIDBDatabase::executeNextDatabaseTask()
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!isMainThread());
</span><ins>+ ASSERT(m_queuedTaskCount);
</ins><span class="cx">
</span><span class="cx"> auto task = m_databaseQueue.tryGetMessage();
</span><span class="cx"> ASSERT(task);
</span><span class="cx">
</span><span class="cx"> task->performTask();
</span><ins>+ --m_queuedTaskCount;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void UniqueIDBDatabase::executeNextDatabaseTaskReply()
</span><span class="cx"> {
</span><span class="cx"> ASSERT(isMainThread());
</span><ins>+ ASSERT(m_queuedTaskCount);
</ins><span class="cx">
</span><span class="cx"> auto task = m_databaseReplyQueue.tryGetMessage();
</span><span class="cx"> ASSERT(task);
</span><span class="cx">
</span><span class="cx"> task->performTask();
</span><ins>+ --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;
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+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);
+}
+
</ins><span class="cx"> void UniqueIDBDatabase::performErrorCallback(uint64_t callbackIdentifier, const IDBError& error)
</span><span class="cx"> {
</span><span class="cx"> auto callback = m_errorCallbacks.take(callbackIdentifier);
</span><del>- ASSERT(callback);
- callback(error);
</del><ins>+ ASSERT(callback || m_hardClosedForUserDelete);
+ if (callback)
+ callback(error);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void UniqueIDBDatabase::performKeyDataCallback(uint64_t callbackIdentifier, const IDBError& error, const IDBKeyData& resultKey)
</span><span class="cx"> {
</span><span class="cx"> auto callback = m_keyDataCallbacks.take(callbackIdentifier);
</span><del>- ASSERT(callback);
- callback(error, resultKey);
</del><ins>+ ASSERT(callback || m_hardClosedForUserDelete);
+ if (callback)
+ callback(error, resultKey);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void UniqueIDBDatabase::performGetResultCallback(uint64_t callbackIdentifier, const IDBError& error, const IDBGetResult& resultData)
</span><span class="cx"> {
</span><span class="cx"> auto callback = m_getResultCallbacks.take(callbackIdentifier);
</span><del>- ASSERT(callback);
- callback(error, resultData);
</del><ins>+ ASSERT(callback || m_hardClosedForUserDelete);
+ if (callback)
+ callback(error, resultData);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void UniqueIDBDatabase::performCountCallback(uint64_t callbackIdentifier, const IDBError& error, uint64_t count)
</span><span class="cx"> {
</span><span class="cx"> auto callback = m_countCallbacks.take(callbackIdentifier);
</span><del>- ASSERT(callback);
- callback(error, count);
</del><ins>+ ASSERT(callback || m_hardClosedForUserDelete);
+ if (callback)
+ callback(error, count);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void UniqueIDBDatabase::forgetErrorCallback(uint64_t callbackIdentifier)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -101,12 +101,15 @@
</span><span class="cx"> void didFinishHandlingVersionChange(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& transactionIdentifier);
</span><span class="cx"> void transactionDestroyed(UniqueIDBDatabaseTransaction&);
</span><span class="cx"> void connectionClosedFromClient(UniqueIDBDatabaseConnection&);
</span><ins>+ void confirmConnectionClosedOnServer(UniqueIDBDatabaseConnection&);
</ins><span class="cx"> void didFireVersionChangeEvent(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier);
</span><span class="cx"> void openDBRequestCancelled(const IDBResourceIdentifier& requestIdentifier);
</span><ins>+ void confirmDidCloseFromServer(UniqueIDBDatabaseConnection&);
</ins><span class="cx">
</span><span class="cx"> void enqueueTransaction(Ref<UniqueIDBDatabaseTransaction>&&);
</span><span class="cx">
</span><span class="cx"> void handleDelete(IDBConnectionToClient&, const IDBRequestData&);
</span><ins>+ void immediateCloseForUserDelete();
</ins><span class="cx">
</span><span class="cx"> static JSC::VM& databaseThreadVM();
</span><span class="cx"> static JSC::ExecState& databaseThreadExecState();
</span><span class="lines">@@ -129,6 +132,8 @@
</span><span class="cx"> void activateTransactionInBackingStore(UniqueIDBDatabaseTransaction&);
</span><span class="cx"> void transactionCompleted(RefPtr<UniqueIDBDatabaseTransaction>&&);
</span><span class="cx">
</span><ins>+ void connectionClosedFromServer(UniqueIDBDatabaseConnection&);
+
</ins><span class="cx"> // Database thread operations
</span><span class="cx"> void deleteBackingStore(const IDBDatabaseIdentifier&);
</span><span class="cx"> void openBackingStore(const IDBDatabaseIdentifier&);
</span><span class="lines">@@ -167,10 +172,10 @@
</span><span class="cx"> void didPerformAbortTransaction(uint64_t callbackIdentifier, const IDBError&, const IDBResourceIdentifier& transactionIdentifier);
</span><span class="cx"> void didPerformActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBError&);
</span><span class="cx">
</span><del>- uint64_t storeCallback(ErrorCallback);
- uint64_t storeCallback(KeyDataCallback);
- uint64_t storeCallback(GetResultCallback);
- uint64_t storeCallback(CountCallback);
</del><ins>+ uint64_t storeCallbackOrFireError(ErrorCallback);
+ uint64_t storeCallbackOrFireError(KeyDataCallback);
+ uint64_t storeCallbackOrFireError(GetResultCallback);
+ uint64_t storeCallbackOrFireError(CountCallback);
</ins><span class="cx">
</span><span class="cx"> void performErrorCallback(uint64_t callbackIdentifier, const IDBError&);
</span><span class="cx"> void performKeyDataCallback(uint64_t callbackIdentifier, const IDBError&, const IDBKeyData&);
</span><span class="lines">@@ -194,6 +199,8 @@
</span><span class="cx"> void executeNextDatabaseTask();
</span><span class="cx"> void executeNextDatabaseTaskReply();
</span><span class="cx">
</span><ins>+ bool doneWithHardClose();
+
</ins><span class="cx"> IDBServer& m_server;
</span><span class="cx"> IDBDatabaseIdentifier m_identifier;
</span><span class="cx">
</span><span class="lines">@@ -201,7 +208,8 @@
</span><span class="cx"> RefPtr<ServerOpenDBRequest> m_currentOpenDBRequest;
</span><span class="cx">
</span><span class="cx"> ListHashSet<RefPtr<UniqueIDBDatabaseConnection>> m_openDatabaseConnections;
</span><del>- HashSet<RefPtr<UniqueIDBDatabaseConnection>> m_closePendingDatabaseConnections;
</del><ins>+ HashSet<RefPtr<UniqueIDBDatabaseConnection>> m_clientClosePendingDatabaseConnections;
+ HashSet<RefPtr<UniqueIDBDatabaseConnection>> m_serverClosePendingDatabaseConnections;
</ins><span class="cx">
</span><span class="cx"> RefPtr<UniqueIDBDatabaseConnection> m_versionChangeDatabaseConnection;
</span><span class="cx"> RefPtr<UniqueIDBDatabaseTransaction> m_versionChangeTransaction;
</span><span class="lines">@@ -235,6 +243,10 @@
</span><span class="cx">
</span><span class="cx"> MessageQueue<CrossThreadTask> m_databaseQueue;
</span><span class="cx"> MessageQueue<CrossThreadTask> m_databaseReplyQueue;
</span><ins>+ std::atomic<uint64_t> m_queuedTaskCount { 0 };
+
+ bool m_hardClosedForUserDelete { false };
+ RefPtr<UniqueIDBDatabase> m_hardCloseProtector;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace IDBServer
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseConnectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -89,6 +89,13 @@
</span><span class="cx"> m_database.connectionClosedFromClient(*this);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void UniqueIDBDatabaseConnection::confirmDidCloseFromServer()
+{
+ LOG(IndexedDB, "UniqueIDBDatabaseConnection::confirmDidCloseFromServer - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
+
+ m_database.confirmDidCloseFromServer(*this);
+}
+
</ins><span class="cx"> void UniqueIDBDatabaseConnection::didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier)
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "UniqueIDBDatabaseConnection::didFireVersionChangeEvent - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseConnectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -74,6 +74,7 @@
</span><span class="cx"> void didDeleteIndex(const IDBResultData&);
</span><span class="cx"> void didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier);
</span><span class="cx"> void didFinishHandlingVersionChange(const IDBResourceIdentifier& transactionIdentifier);
</span><ins>+ void confirmDidCloseFromServer();
</ins><span class="cx">
</span><span class="cx"> void abortTransactionWithoutCallback(UniqueIDBDatabaseTransaction&);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBErrorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -65,6 +65,11 @@
</span><span class="cx"> return IDBDatabaseException::getErrorDescription(m_code);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+RefPtr<DOMError> IDBError::toDOMError() const
+{
+ return DOMError::create(IDBDatabaseException::getErrorName(m_code), m_message);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBErrorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -23,11 +23,11 @@
</span><span class="cx"> * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> */
</span><span class="cx">
</span><del>-#ifndef IDBError_h
-#define IDBError_h
</del><ins>+#pragma once
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx">
</span><ins>+#include "DOMError.h"
</ins><span class="cx"> #include "IDBDatabaseException.h"
</span><span class="cx"> #include <wtf/text/WTFString.h>
</span><span class="cx">
</span><span class="lines">@@ -39,8 +39,15 @@
</span><span class="cx"> IDBError(ExceptionCode);
</span><span class="cx"> IDBError(ExceptionCode, const String& message);
</span><span class="cx">
</span><ins>+ static IDBError userDeleteError()
+ {
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Database deleted by request of the user") };
+ }
+
</ins><span class="cx"> IDBError& operator=(const IDBError&);
</span><span class="cx">
</span><ins>+ RefPtr<DOMError> toDOMError() const;
+
</ins><span class="cx"> ExceptionCode code() const { return m_code; }
</span><span class="cx"> String name() const;
</span><span class="cx"> String message() const;
</span><span class="lines">@@ -78,4 +85,3 @@
</span><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span><del>-#endif // IDBError_h
</del></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedInProcessIDBServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -367,6 +367,15 @@
</span><span class="cx"> });
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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);
+ });
+}
+
</ins><span class="cx"> void InProcessIDBServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
</span><span class="cx"> {
</span><span class="cx"> RefPtr<InProcessIDBServer> protectedThis(this);
</span><span class="lines">@@ -407,6 +416,14 @@
</span><span class="cx"> });
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void InProcessIDBServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
+{
+ RefPtr<InProcessIDBServer> protectedThis(this);
+ RunLoop::current().dispatch([this, protectedThis, databaseConnectionIdentifier] {
+ m_server->confirmDidCloseFromServer(databaseConnectionIdentifier);
+ });
+}
+
</ins><span class="cx"> void InProcessIDBServer::getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
</span><span class="cx"> {
</span><span class="cx"> RefPtr<InProcessIDBServer> protectedThis(this);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedInProcessIDBServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -52,6 +52,7 @@
</span><span class="cx">
</span><span class="cx"> WEBCORE_EXPORT IDBClient::IDBConnectionToServer& connectionToServer() const;
</span><span class="cx"> IDBServer::IDBConnectionToClient& connectionToClient() const;
</span><ins>+ IDBServer::IDBServer& server() { return m_server.get(); }
</ins><span class="cx">
</span><span class="cx"> IDBServer::IDBServer& idbServer() { return m_server.get(); }
</span><span class="cx">
</span><span class="lines">@@ -77,6 +78,7 @@
</span><span class="cx"> void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier) final;
</span><span class="cx"> void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier) final;
</span><span class="cx"> void openDBRequestCancelled(const IDBRequestData&) final;
</span><ins>+ void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier) final;
</ins><span class="cx"> void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) final;
</span><span class="cx">
</span><span class="cx"> // IDBConnectionToClient
</span><span class="lines">@@ -98,6 +100,7 @@
</span><span class="cx"> void didIterateCursor(const IDBResultData&) final;
</span><span class="cx"> void fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion) final;
</span><span class="cx"> void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) final;
</span><ins>+ void didCloseFromServer(IDBServer::UniqueIDBDatabaseConnection&, const IDBError&) final;
</ins><span class="cx"> void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) final;
</span><span class="cx"> void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) final;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformCrossThreadCopiercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/CrossThreadCopier.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -85,6 +85,11 @@
</span><span class="cx"> return ThreadSafeDataBuffer(buffer);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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;
+}
+
</ins><span class="cx"> // Test CrossThreadCopier using COMPILE_ASSERT.
</span><span class="cx">
</span><span class="cx"> // Verify that ThreadSafeRefCounted objects get handled correctly.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformCrossThreadCopierh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/CrossThreadCopier.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -160,6 +160,11 @@
</span><span class="cx"> static Type copy(const ThreadSafeDataBuffer&);
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+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);
+};
+
</ins><span class="cx"> template<typename T>
</span><span class="cx"> struct CrossThreadCopier : public CrossThreadCopierBase<CrossThreadCopierBaseHelper::IsEnumOrConvertibleToInteger<T>::value, CrossThreadCopierBaseHelper::IsThreadSafeRefCountedPointer<T>::value, T> {
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,5 +1,32 @@
</span><span class="cx"> 2016-05-18 Brady Eidson <beidson@apple.com>
</span><span class="cx">
</span><ins>+ 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 <beidson@apple.com>
+
</ins><span class="cx"> Modern IDB: Make TestRunner.clearAllDatabases also delete IndexedDB databases (once doing so is supported).
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=157823
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessDatabaseProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014, 2015, 2016 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -259,13 +259,8 @@
</span><span class="cx"> }));
</span><span class="cx">
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><del>- if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
- postDatabaseTask(std::make_unique<CrossThreadTask>([this, callbackAggregator, modifiedSince] {
-
- deleteIndexedDatabaseEntriesModifiedSince(modifiedSince);
- RunLoop::main().dispatch([callbackAggregator] { });
- }));
- }
</del><ins>+ if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases))
+ m_idbServer->closeAndDeleteDatabasesModifiedSince(modifiedSince, [callbackAggregator] { });
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessIndexedDBWebIDBConnectionToClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -127,6 +127,11 @@
</span><span class="cx">
</span><span class="cx"> void WebIDBConnectionToClient::didGetRecord(const WebCore::IDBResultData& resultData)
</span><span class="cx"> {
</span><ins>+ if (resultData.type() == IDBResultType::Error) {
+ send(Messages::WebIDBConnectionToServer::DidGetRecord(resultData));
+ return;
+ }
+
</ins><span class="cx"> auto& blobFilePaths = resultData.getResult().value().blobFilePaths();
</span><span class="cx"> if (blobFilePaths.isEmpty()) {
</span><span class="cx"> send(Messages::WebIDBConnectionToServer::DidGetRecord(resultData));
</span><span class="lines">@@ -169,6 +174,11 @@
</span><span class="cx"> send(Messages::WebIDBConnectionToServer::DidStartTransaction(transactionIdentifier, error));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebIDBConnectionToClient::didCloseFromServer(WebCore::IDBServer::UniqueIDBDatabaseConnection& connection, const WebCore::IDBError& error)
+{
+ send(Messages::WebIDBConnectionToServer::DidCloseFromServer(connection.identifier(), error));
+}
+
</ins><span class="cx"> void WebIDBConnectionToClient::notifyOpenDBRequestBlocked(const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
</span><span class="cx"> {
</span><span class="cx"> send(Messages::WebIDBConnectionToServer::NotifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion));
</span><span class="lines">@@ -294,6 +304,11 @@
</span><span class="cx"> DatabaseProcess::singleton().idbServer().openDBRequestCancelled(requestData);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebIDBConnectionToClient::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
+{
+ DatabaseProcess::singleton().idbServer().confirmDidCloseFromServer(databaseConnectionIdentifier);
+}
+
</ins><span class="cx"> void WebIDBConnectionToClient::getAllDatabaseNames(uint64_t serverConnectionIdentifier, const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID)
</span><span class="cx"> {
</span><span class="cx"> DatabaseProcess::singleton().idbServer().getAllDatabaseNames(serverConnectionIdentifier, topOrigin, openingOrigin, callbackID);
</span></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessIndexedDBWebIDBConnectionToClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -23,8 +23,7 @@
</span><span class="cx"> * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> */
</span><span class="cx">
</span><del>-#ifndef WebIDBConnectionToClient_h
-#define WebIDBConnectionToClient_h
</del><ins>+#pragma once
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx">
</span><span class="lines">@@ -76,6 +75,7 @@
</span><span class="cx">
</span><span class="cx"> void fireVersionChangeEvent(WebCore::IDBServer::UniqueIDBDatabaseConnection&, const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion) final;
</span><span class="cx"> void didStartTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier, const WebCore::IDBError&) final;
</span><ins>+ void didCloseFromServer(WebCore::IDBServer::UniqueIDBDatabaseConnection&, const WebCore::IDBError&) final;
</ins><span class="cx"> void notifyOpenDBRequestBlocked(const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) final;
</span><span class="cx">
</span><span class="cx"> void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) final;
</span><span class="lines">@@ -106,6 +106,7 @@
</span><span class="cx"> void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier);
</span><span class="cx"> void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier);
</span><span class="cx"> void openDBRequestCancelled(const WebCore::IDBRequestData&);
</span><ins>+ void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
</ins><span class="cx">
</span><span class="cx"> void getAllDatabaseNames(uint64_t serverConnectionIdentifier, const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID);
</span><span class="cx">
</span><span class="lines">@@ -127,4 +128,3 @@
</span><span class="cx"> } // namespace WebKit
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span><del>-#endif // WebIDBConnectionToClient_h
</del></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessIndexedDBWebIDBConnectionToClientmessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> AbortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier transactionIdentifier);
</span><span class="cx"> DidFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier requestIdentifier);
</span><span class="cx"> OpenDBRequestCancelled(WebCore::IDBRequestData requestData);
</span><ins>+ ConfirmDidCloseFromServer(uint64_t databaseConnectionIdentifier);
</ins><span class="cx">
</span><span class="cx"> GetAllDatabaseNames(uint64_t serverConnectionIdentifier, struct WebCore::SecurityOriginData topOrigin, struct WebCore::SecurityOriginData openingOrigin, uint64_t callbackID);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessDatabasesIndexedDBWebIDBConnectionToServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -186,6 +186,11 @@
</span><span class="cx"> send(Messages::WebIDBConnectionToClient::OpenDBRequestCancelled(requestData));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebIDBConnectionToServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
+{
+ send(Messages::WebIDBConnectionToClient::ConfirmDidCloseFromServer(databaseConnectionIdentifier));
+}
+
</ins><span class="cx"> void WebIDBConnectionToServer::getAllDatabaseNames(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID)
</span><span class="cx"> {
</span><span class="cx"> send(Messages::WebIDBConnectionToClient::GetAllDatabaseNames(m_identifier, topOrigin, openingOrigin, callbackID));
</span><span class="lines">@@ -282,11 +287,16 @@
</span><span class="cx"> m_connectionToServer->fireVersionChangeEvent(uniqueDatabaseConnectionIdentifier, requestIdentifier, requestedVersion);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void WebIDBConnectionToServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const WebCore::IDBError& error)
</del><ins>+void WebIDBConnectionToServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
</ins><span class="cx"> {
</span><span class="cx"> m_connectionToServer->didStartTransaction(transactionIdentifier, error);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebIDBConnectionToServer::didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError& error)
+{
+ m_connectionToServer->didCloseFromServer(databaseConnectionIdentifier, error);
+}
+
</ins><span class="cx"> void WebIDBConnectionToServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
</span><span class="cx"> {
</span><span class="cx"> m_connectionToServer->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessDatabasesIndexedDBWebIDBConnectionToServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -23,8 +23,7 @@
</span><span class="cx"> * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> */
</span><span class="cx">
</span><del>-#ifndef WebIDBConnectionToServer_h
-#define WebIDBConnectionToServer_h
</del><ins>+#pragma once
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx">
</span><span class="lines">@@ -66,6 +65,7 @@
</span><span class="cx"> void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier) final;
</span><span class="cx"> void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier) final;
</span><span class="cx"> void openDBRequestCancelled(const WebCore::IDBRequestData&) final;
</span><ins>+ void confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier) final;
</ins><span class="cx">
</span><span class="cx"> void getAllDatabaseNames(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID) final;
</span><span class="cx">
</span><span class="lines">@@ -91,6 +91,7 @@
</span><span class="cx"> void didIterateCursor(const WebCore::IDBResultData&);
</span><span class="cx"> void fireVersionChangeEvent(uint64_t uniqueDatabaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
</span><span class="cx"> void didStartTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier, const WebCore::IDBError&);
</span><ins>+ void didCloseFromServer(uint64_t databaseConnectionIdentifier, const WebCore::IDBError&);
</ins><span class="cx"> void notifyOpenDBRequestBlocked(const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
</span><span class="cx"> void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames);
</span><span class="cx">
</span><span class="lines">@@ -109,4 +110,3 @@
</span><span class="cx"> } // namespace WebKit
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span><del>-#endif // WebIDBConnectionToServer_h
</del></span></pre></div>
<a id="trunkSourceWebKit2WebProcessDatabasesIndexedDBWebIDBConnectionToServermessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in (201097 => 201098)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx">
</span><span class="cx"> FireVersionChangeEvent(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier requestIdentifier, uint64_t requestedVersion)
</span><span class="cx"> DidStartTransaction(WebCore::IDBResourceIdentifier transactionIdentifier, WebCore::IDBError error)
</span><ins>+ DidCloseFromServer(uint64_t databaseConnectionIdentifier, WebCore::IDBError error) final;
</ins><span class="cx"> NotifyOpenDBRequestBlocked(WebCore::IDBResourceIdentifier requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
</span><span class="cx">
</span><span class="cx"> DidGetAllDatabaseNames(uint64_t callbackID, Vector<String> databaseNames)
</span></span></pre>
</div>
</div>
</body>
</html>