<!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>[201195] 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/201195">201195</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2016-05-19 15:58:13 -0700 (Thu, 19 May 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Finishing off: Modern IDB: Website data store management.
https://bugs.webkit.org/show_bug.cgi?id=157626
Reviewed by Alex Christensen.
Source/WebCore:
Test: storage/indexeddb/modern/new-database-after-user-delete.html
This patch does two primary things:
1 - Implements the actual "delete files on disk" code for unopened databases,
taken from existing WK2 code.
2 - When a UniqueIBDDatabase is told to close immediately for user delete, it also
queues up a "delete backing store unconditionally" operation in the database task queue.
That way, all of the open databases are deleted before the primary "delete all files"
pass, and they are also deleted before any future openDB requests are handled that might
recreate the files.
* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::getOrCreateUniqueIDBDatabase):
(WebCore::IDBServer::IDBServer::deleteDatabase):
(WebCore::IDBServer::IDBServer::closeUniqueIDBDatabase):
(WebCore::IDBServer::IDBServer::openDBRequestCancelled):
(WebCore::IDBServer::removeAllDatabasesForOriginPath):
(WebCore::IDBServer::IDBServer::performCloseAndDeleteDatabasesModifiedSince):
(WebCore::IDBServer::IDBServer::performCloseAndDeleteDatabasesForOrigins):
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::performUnconditionalDeleteBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::doneWithHardClose):
(WebCore::IDBServer::UniqueIDBDatabase::immediateCloseForUserDelete):
* Modules/indexeddb/server/UniqueIDBDatabase.h:
Source/WebKit2:
* DatabaseProcess/DatabaseProcess.cpp:
(WebKit::DatabaseProcess::deleteWebsiteDataForOrigins):
(WebKit::removeAllDatabasesForOriginPath): Deleted.
(WebKit::DatabaseProcess::deleteIndexedDatabaseEntriesForOrigins): Deleted.
(WebKit::DatabaseProcess::deleteIndexedDatabaseEntriesModifiedSince): Deleted.
* DatabaseProcess/DatabaseProcess.h:
LayoutTests:
* storage/indexeddb/modern/new-database-after-user-delete-expected.txt: Added.
* storage/indexeddb/modern/new-database-after-user-delete.html: Added.
* storage/indexeddb/modern/resources/new-database-after-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="#trunkSourceWebCoreModulesindexeddbserverIDBServercpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp</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="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessDatabaseProcesscpp">trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessDatabaseProcessh">trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernnewdatabaseafteruserdeleteexpectedtxt">trunk/LayoutTests/storage/indexeddb/modern/new-database-after-user-delete-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernnewdatabaseafteruserdeletehtml">trunk/LayoutTests/storage/indexeddb/modern/new-database-after-user-delete.html</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernresourcesnewdatabaseafteruserdeletejs">trunk/LayoutTests/storage/indexeddb/modern/resources/new-database-after-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 (201194 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-05-19 22:55:04 UTC (rev 201194)
+++ trunk/LayoutTests/ChangeLog        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-05-19 Brady Eidson <beidson@apple.com>
+
+ Finishing off: Modern IDB: Website data store management.
+ https://bugs.webkit.org/show_bug.cgi?id=157626
+
+ Reviewed by Alex Christensen.
+
+ * storage/indexeddb/modern/new-database-after-user-delete-expected.txt: Added.
+ * storage/indexeddb/modern/new-database-after-user-delete.html: Added.
+ * storage/indexeddb/modern/resources/new-database-after-user-delete.js: Added.
+
</ins><span class="cx"> 2016-05-19 Enrica Casucci <enrica@apple.com>
</span><span class="cx">
</span><span class="cx"> Drag cannot start if no drag data is available in the Pasteboard.
</span></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernnewdatabaseafteruserdeleteexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/new-database-after-user-delete-expected.txt (0 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/new-database-after-user-delete-expected.txt         (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/new-database-after-user-delete-expected.txt        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+Tests that if you perform a user delete with an open database connection, and then you re-open the same database, that the new database is actually new.
+
+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
+Created an objectStore an put a value in it
+Value was stored in objectStore
+Version change transaction completed. Version is now 1. About to request clearAllDatabases
+Requested clearAllDatabases
+Database connection error'ed out. Opening a new connection.
+Reopened upgrade needed: Old version - 0 New version - 1
+[PASS] The database has no object stores, meaning it is new
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernnewdatabaseafteruserdeletehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/new-database-after-user-delete.html (0 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/new-database-after-user-delete.html         (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/new-database-after-user-delete.html        2016-05-19 22:58:13 UTC (rev 201195)
</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/new-database-after-user-delete.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernresourcesnewdatabaseafteruserdeletejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/resources/new-database-after-user-delete.js (0 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/resources/new-database-after-user-delete.js         (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/resources/new-database-after-user-delete.js        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+description("Tests that if you perform a user delete with an open database connection, and then you re-open the same database, that the new database is actually new.");
+
+indexedDBTest(prepareDatabase);
+
+function done()
+{
+ finishJSTest();
+}
+
+function log(message)
+{
+ debug(message);
+}
+
+var dbName;
+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;
+ dbName = database.name;
+
+ var objectStore = database.createObjectStore("TestObjectStore");
+ objectStore.put("bar", "foo").onsuccess = function() {
+ log("Value was stored in objectStore");
+ };
+
+ log("Created an objectStore an put a value in it");
+
+ database.onerror = function(event) {
+ log("Database connection error'ed out. Opening a new connection.");
+ continueTest();
+ }
+
+ versionTransaction.onabort = function(event) {
+ log("Initial upgrade versionchange transaction unexpected abort: " + event.type + " " + versionTransaction.error.name + ", " + versionTransaction.error.message);
+ done();
+ }
+
+ versionTransaction.oncomplete = function() {
+ log("Version change transaction completed. Version is now " + database.version + ". About to request clearAllDatabases");
+ if (window.testRunner) {
+ setTimeout("testRunner.clearAllDatabases();", 0);
+ log("Requested clearAllDatabases");
+ }
+ }
+
+ versionTransaction.onerror = function(event) {
+ log("Initial upgrade versionchange transaction unexpected error: " + event.type + " " + versionTransaction.error.name + ", " + versionTransaction.error.message);
+ done();
+ }
+}
+
+function continueTest()
+{
+ var openReq = indexedDB.open(dbName);
+
+ openReq.onblocked = function() {
+ log("Second open request unexpected blocked");
+ done();
+ }
+
+ openReq.onupgradeneeded = function(event) {
+ log("Reopened upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+ if (event.target.result.objectStoreNames.length)
+ log("[FAIL] The database has object stores already, but shouldn't");
+ else
+ log("[PASS] The database has no object stores, meaning it is new");
+ done();
+ }
+
+ openReq.onsuccess = function() {
+ log("Second open request unexpected success");
+ done();
+ }
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (201194 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-05-19 22:55:04 UTC (rev 201194)
+++ trunk/Source/WebCore/ChangeLog        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -1,5 +1,40 @@
</span><span class="cx"> 2016-05-19 Brady Eidson <beidson@apple.com>
</span><span class="cx">
</span><ins>+ Finishing off: Modern IDB: Website data store management.
+ https://bugs.webkit.org/show_bug.cgi?id=157626
+
+ Reviewed by Alex Christensen.
+
+ Test: storage/indexeddb/modern/new-database-after-user-delete.html
+
+ This patch does two primary things:
+ 1 - Implements the actual "delete files on disk" code for unopened databases,
+ taken from existing WK2 code.
+
+ 2 - When a UniqueIBDDatabase is told to close immediately for user delete, it also
+ queues up a "delete backing store unconditionally" operation in the database task queue.
+
+ That way, all of the open databases are deleted before the primary "delete all files"
+ pass, and they are also deleted before any future openDB requests are handled that might
+ recreate the files.
+
+ * Modules/indexeddb/server/IDBServer.cpp:
+ (WebCore::IDBServer::IDBServer::getOrCreateUniqueIDBDatabase):
+ (WebCore::IDBServer::IDBServer::deleteDatabase):
+ (WebCore::IDBServer::IDBServer::closeUniqueIDBDatabase):
+ (WebCore::IDBServer::IDBServer::openDBRequestCancelled):
+ (WebCore::IDBServer::removeAllDatabasesForOriginPath):
+ (WebCore::IDBServer::IDBServer::performCloseAndDeleteDatabasesModifiedSince):
+ (WebCore::IDBServer::IDBServer::performCloseAndDeleteDatabasesForOrigins):
+
+ * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+ (WebCore::IDBServer::UniqueIDBDatabase::performUnconditionalDeleteBackingStore):
+ (WebCore::IDBServer::UniqueIDBDatabase::doneWithHardClose):
+ (WebCore::IDBServer::UniqueIDBDatabase::immediateCloseForUserDelete):
+ * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
+2016-05-19 Brady Eidson <beidson@apple.com>
+
</ins><span class="cx"> REGRESSION(201098) GuardMalloc / ASan crashes in WebCore::IDBServer::UniqueIDBDatabase::executeNextDatabaseTaskReply
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=157917
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (201194 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp        2016-05-19 22:55:04 UTC (rev 201194)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -111,6 +111,8 @@
</span><span class="cx">
</span><span class="cx"> UniqueIDBDatabase& IDBServer::getOrCreateUniqueIDBDatabase(const IDBDatabaseIdentifier& identifier)
</span><span class="cx"> {
</span><ins>+ ASSERT(isMainThread());
+
</ins><span class="cx"> auto uniqueIDBDatabase = m_uniqueIDBDatabaseMap.add(identifier, nullptr);
</span><span class="cx"> if (uniqueIDBDatabase.isNewEntry)
</span><span class="cx"> uniqueIDBDatabase.iterator->value = UniqueIDBDatabase::create(*this, identifier);
</span><span class="lines">@@ -147,7 +149,8 @@
</span><span class="cx"> void IDBServer::deleteDatabase(const IDBRequestData& requestData)
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBServer::deleteDatabase - %s", requestData.databaseIdentifier().debugString().utf8().data());
</span><del>-
</del><ins>+ ASSERT(isMainThread());
+
</ins><span class="cx"> auto connection = m_connectionMap.get(requestData.requestIdentifier().connectionIdentifier());
</span><span class="cx"> if (!connection) {
</span><span class="cx"> // If the connection back to the client is gone, there's no way to delete the database as
</span><span class="lines">@@ -165,9 +168,9 @@
</span><span class="cx"> void IDBServer::closeUniqueIDBDatabase(UniqueIDBDatabase& database)
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBServer::closeUniqueIDBDatabase");
</span><ins>+ ASSERT(isMainThread());
</ins><span class="cx">
</span><del>- auto deletedDatabase = m_uniqueIDBDatabaseMap.take(database.identifier());
- ASSERT_UNUSED(deletedDatabase, deletedDatabase.get() == &database);
</del><ins>+ m_uniqueIDBDatabaseMap.remove(database.identifier());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void IDBServer::abortTransaction(const IDBResourceIdentifier& transactionIdentifier)
</span><span class="lines">@@ -382,6 +385,7 @@
</span><span class="cx"> void IDBServer::openDBRequestCancelled(const IDBRequestData& requestData)
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBServer::openDBRequestCancelled");
</span><ins>+ ASSERT(isMainThread());
</ins><span class="cx">
</span><span class="cx"> auto* uniqueIDBDatabase = m_uniqueIDBDatabaseMap.get(requestData.databaseIdentifier());
</span><span class="cx"> if (!uniqueIDBDatabase)
</span><span class="lines">@@ -530,15 +534,52 @@
</span><span class="cx"> postDatabaseTask(createCrossThreadTask(*this, &IDBServer::performCloseAndDeleteDatabasesForOrigins, origins, callbackID));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void IDBServer::performCloseAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point, uint64_t callbackID)
</del><ins>+static void removeAllDatabasesForOriginPath(const String& originPath, std::chrono::system_clock::time_point modifiedSince)
</ins><span class="cx"> {
</span><del>- // FIXME: Implement deleting the files.
</del><ins>+ Vector<String> databasePaths = listDirectory(originPath, "*");
+
+ for (auto& databasePath : databasePaths) {
+ String databaseFile = pathByAppendingComponent(databasePath, "IndexedDB.sqlite3");
+
+ if (!fileExists(databaseFile))
+ continue;
+
+ if (modifiedSince > std::chrono::system_clock::time_point::min()) {
+ time_t modificationTime;
+ if (!getFileModificationTime(databaseFile, modificationTime))
+ continue;
+
+ if (std::chrono::system_clock::from_time_t(modificationTime) < modifiedSince)
+ continue;
+ }
+
+ SQLiteFileSystem::deleteDatabaseFile(databaseFile);
+ deleteEmptyDirectory(databasePath);
+ }
+
+ deleteEmptyDirectory(originPath);
+}
+
+void IDBServer::performCloseAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID)
+{
+ if (!m_databaseDirectoryPath.isEmpty()) {
+ Vector<String> originPaths = listDirectory(m_databaseDirectoryPath, "*");
+ for (auto& originPath : originPaths)
+ removeAllDatabasesForOriginPath(originPath, modifiedSince);
+ }
+
</ins><span class="cx"> postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didPerformCloseAndDeleteDatabases, callbackID));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void IDBServer::performCloseAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>&, uint64_t callbackID)
</del><ins>+void IDBServer::performCloseAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>& origins, uint64_t callbackID)
</ins><span class="cx"> {
</span><del>- // FIXME: Implement deleting the files.
</del><ins>+ if (!m_databaseDirectoryPath.isEmpty()) {
+ for (const auto& origin : origins) {
+ String originPath = pathByAppendingComponent(m_databaseDirectoryPath, origin.securityOrigin()->databaseIdentifier());
+ removeAllDatabasesForOriginPath(originPath, std::chrono::system_clock::time_point::min());
+ }
+ }
+
</ins><span class="cx"> postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didPerformCloseAndDeleteDatabases, callbackID));
</span><span class="cx"> }
</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 (201194 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2016-05-19 22:55:04 UTC (rev 201194)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -246,6 +246,20 @@
</span><span class="cx"> postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didDeleteBackingStore, deletedVersion));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void UniqueIDBDatabase::performUnconditionalDeleteBackingStore()
+{
+ ASSERT(!isMainThread());
+ LOG(IndexedDB, "(db) UniqueIDBDatabase::performUnconditionalDeleteBackingStore");
+
+ if (!m_backingStore)
+ return;
+
+ m_backingStore->deleteBackingStore();
+ m_backingStore = nullptr;
+ m_backingStoreSupportsSimultaneousTransactions = false;
+ m_backingStoreIsEphemeral = false;
+}
+
</ins><span class="cx"> void UniqueIDBDatabase::didDeleteBackingStore(uint64_t deletedVersion)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="lines">@@ -1530,7 +1544,7 @@
</span><span class="cx">
</span><span class="cx"> bool UniqueIDBDatabase::doneWithHardClose()
</span><span class="cx"> {
</span><del>- return (!m_queuedTaskCount && m_serverClosePendingDatabaseConnections.isEmpty());
</del><ins>+ return !m_queuedTaskCount && m_clientClosePendingDatabaseConnections.isEmpty() && m_serverClosePendingDatabaseConnections.isEmpty();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> static void errorOpenDBRequestForUserDelete(ServerOpenDBRequest& request)
</span><span class="lines">@@ -1605,9 +1619,11 @@
</span><span class="cx"> // Set up the database to remain alive-but-inert until all of its background activity finishes and all
</span><span class="cx"> // database connections confirm that they have closed.
</span><span class="cx"> m_hardClosedForUserDelete = true;
</span><del>- if (!doneWithHardClose())
- m_hardCloseProtector = this;
</del><ins>+ m_hardCloseProtector = this;
</ins><span class="cx">
</span><ins>+ // Have the database unconditionally delete itself on the database task queue.
+ postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performUnconditionalDeleteBackingStore));
+
</ins><span class="cx"> // Remove the database from the IDBServer's set of open databases.
</span><span class="cx"> // If there is no in-progress background thread activity for this database, it will be deleted here.
</span><span class="cx"> m_server.closeUniqueIDBDatabase(*this);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (201194 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h        2016-05-19 22:55:04 UTC (rev 201194)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -153,6 +153,7 @@
</span><span class="cx"> void performOpenCursor(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo&);
</span><span class="cx"> void performIterateCursor(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData&, unsigned long count);
</span><span class="cx"> void performActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBTransactionInfo&);
</span><ins>+ void performUnconditionalDeleteBackingStore();
</ins><span class="cx">
</span><span class="cx"> // Main thread callbacks
</span><span class="cx"> void didDeleteBackingStore(uint64_t deletedVersion);
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (201194 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-05-19 22:55:04 UTC (rev 201194)
+++ trunk/Source/WebKit2/ChangeLog        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-05-19 Brady Eidson <beidson@apple.com>
+
+ Finishing off: Modern IDB: Website data store management.
+ https://bugs.webkit.org/show_bug.cgi?id=157626
+
+ Reviewed by Alex Christensen.
+
+ * DatabaseProcess/DatabaseProcess.cpp:
+ (WebKit::DatabaseProcess::deleteWebsiteDataForOrigins):
+ (WebKit::removeAllDatabasesForOriginPath): Deleted.
+ (WebKit::DatabaseProcess::deleteIndexedDatabaseEntriesForOrigins): Deleted.
+ (WebKit::DatabaseProcess::deleteIndexedDatabaseEntriesModifiedSince): Deleted.
+ * DatabaseProcess/DatabaseProcess.h:
+
</ins><span class="cx"> 2016-05-19 Brent Fulgham <bfulgham@apple.com>
</span><span class="cx">
</span><span class="cx"> [OS X][WK2] Expand sandbox for new mach endpoints
</span></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessDatabaseProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp (201194 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp        2016-05-19 22:55:04 UTC (rev 201194)
+++ trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -287,17 +287,8 @@
</span><span class="cx"> }));
</span><span class="cx">
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><del>- if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
- Vector<RefPtr<WebCore::SecurityOrigin>> securityOrigins;
- for (const auto& securityOriginData : securityOriginDatas)
- securityOrigins.append(securityOriginData.securityOrigin());
-
- postDatabaseTask(std::make_unique<CrossThreadTask>([this, securityOrigins, callbackAggregator] {
- deleteIndexedDatabaseEntriesForOrigins(securityOrigins);
-
- RunLoop::main().dispatch([callbackAggregator] { });
- }));
- }
</del><ins>+ if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases))
+ idbServer().closeAndDeleteDatabasesForOrigins(securityOriginDatas, [callbackAggregator] { });
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -345,59 +336,6 @@
</span><span class="cx"> return securityOrigins;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static void removeAllDatabasesForOriginPath(const String& originPath, std::chrono::system_clock::time_point modifiedSince)
-{
- // FIXME: We should also close/invalidate any live handles to the database files we are about to delete.
- // Right now:
- // - For read-only operations, they will continue functioning as normal on the unlinked file.
- // - For write operations, they will start producing errors as SQLite notices the missing backing store.
- // This is tracked by https://bugs.webkit.org/show_bug.cgi?id=135347
-
- Vector<String> databasePaths = listDirectory(originPath, "*");
-
- for (auto& databasePath : databasePaths) {
- String databaseFile = pathByAppendingComponent(databasePath, "IndexedDB.sqlite3");
-
- if (!fileExists(databaseFile))
- continue;
-
- if (modifiedSince > std::chrono::system_clock::time_point::min()) {
- time_t modificationTime;
- if (!getFileModificationTime(databaseFile, modificationTime))
- continue;
-
- if (std::chrono::system_clock::from_time_t(modificationTime) < modifiedSince)
- continue;
- }
-
- deleteFile(databaseFile);
- deleteEmptyDirectory(databasePath);
- }
-
- deleteEmptyDirectory(originPath);
-}
-
-void DatabaseProcess::deleteIndexedDatabaseEntriesForOrigins(const Vector<RefPtr<WebCore::SecurityOrigin>>& securityOrigins)
-{
- if (m_indexedDatabaseDirectory.isEmpty())
- return;
-
- for (const auto& securityOrigin : securityOrigins) {
- String originPath = pathByAppendingComponent(m_indexedDatabaseDirectory, securityOrigin->databaseIdentifier());
-
- removeAllDatabasesForOriginPath(originPath, std::chrono::system_clock::time_point::min());
- }
-}
-
-void DatabaseProcess::deleteIndexedDatabaseEntriesModifiedSince(std::chrono::system_clock::time_point modifiedSince)
-{
- if (m_indexedDatabaseDirectory.isEmpty())
- return;
-
- Vector<String> originPaths = listDirectory(m_indexedDatabaseDirectory, "*");
- for (auto& originPath : originPaths)
- removeAllDatabasesForOriginPath(originPath, modifiedSince);
-}
</del><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> void DatabaseProcess::getSandboxExtensionsForBlobFiles(const Vector<String>& filenames, std::function<void (const SandboxExtension::HandleArray&)> completionHandler)
</span></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessDatabaseProcessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h (201194 => 201195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h        2016-05-19 22:55:04 UTC (rev 201194)
+++ trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h        2016-05-19 22:58:13 UTC (rev 201195)
</span><span class="lines">@@ -110,8 +110,6 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> Vector<RefPtr<WebCore::SecurityOrigin>> indexedDatabaseOrigins();
</span><del>- void deleteIndexedDatabaseEntriesForOrigins(const Vector<RefPtr<WebCore::SecurityOrigin>>&);
- void deleteIndexedDatabaseEntriesModifiedSince(std::chrono::system_clock::time_point modifiedSince);
</del><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> // For execution on work queue thread only
</span></span></pre>
</div>
</div>
</body>
</html>