Diff
Modified: trunk/LayoutTests/ChangeLog (181576 => 181577)
--- trunk/LayoutTests/ChangeLog 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/LayoutTests/ChangeLog 2015-03-16 20:20:27 UTC (rev 181577)
@@ -1,3 +1,19 @@
+2015-03-16 Chris Dumez <cdu...@apple.com>
+
+ Make DatabaseContext suspendable if there is no pending database activity
+ https://bugs.webkit.org/show_bug.cgi?id=142716
+ <rdar://problem/19923085>
+
+ Reviewed by Andreas Kling.
+
+ Add layout tests to check page-cacheability when WebSQL is used,
+ depending if there is pending database activity or not.
+
+ * fast/history/page-cache-webdatabase-no-transaction-db-expected.txt: Added.
+ * fast/history/page-cache-webdatabase-no-transaction-db.html: Copied from LayoutTests/fast/history/page-cache-webdatabase-opened-db.html.
+ * fast/history/page-cache-webdatabase-pending-transaction-expected.txt: Renamed from LayoutTests/fast/history/page-cache-webdatabase-opened-db-expected.txt.
+ * fast/history/page-cache-webdatabase-pending-transaction.html: Renamed from LayoutTests/fast/history/page-cache-webdatabase-opened-db.html.
+
2015-03-16 Dean Jackson <d...@apple.com>
Parsing and Style Resolution of Container-based Animation Triggers
Added: trunk/LayoutTests/fast/history/page-cache-webdatabase-no-transaction-db-expected.txt (0 => 181577)
--- trunk/LayoutTests/fast/history/page-cache-webdatabase-no-transaction-db-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/history/page-cache-webdatabase-no-transaction-db-expected.txt 2015-03-16 20:20:27 UTC (rev 181577)
@@ -0,0 +1,13 @@
+Tests that a page with an open WebDatabase with no pending transaction goes into the page cache.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+pageshow - not from cache
+pagehide - entering cache
+pageshow - from cache
+PASS Page did enter and was restored from the page cache
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Copied: trunk/LayoutTests/fast/history/page-cache-webdatabase-no-transaction-db.html (from rev 181576, trunk/LayoutTests/fast/history/page-cache-webdatabase-opened-db.html) (0 => 181577)
--- trunk/LayoutTests/fast/history/page-cache-webdatabase-no-transaction-db.html (rev 0)
+++ trunk/LayoutTests/fast/history/page-cache-webdatabase-no-transaction-db.html 2015-03-16 20:20:27 UTC (rev 181577)
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description('Tests that a page with an open WebDatabase with no pending transaction goes into the page cache.');
+window.jsTestIsAsync = true;
+
+if (window.testRunner) {
+ testRunner.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
+ testRunner.clearAllDatabases();
+}
+
+window.addEventListener("pageshow", function(event) {
+ debug("pageshow - " + (event.persisted ? "" : "not ") + "from cache");
+ if (event.persisted) {
+ testPassed("Page did enter and was restored from the page cache");
+ finishJSTest();
+ }
+}, false);
+
+window.addEventListener("pagehide", function(event) {
+ debug("pagehide - " + (event.persisted ? "" : "not ") + "entering cache");
+ if (!event.persisted) {
+ testFailed("Page did not enter the page cache.");
+ finishJSTest();
+ }
+}, false);
+
+window.addEventListener('load', function() {
+ // Open the database.
+ var db = openDatabase("PageCacheTest", "", "Page Cache Test", 10, function (createdDb) {
+ setTimeout(function() {
+ window.location.href = ""
+ }, 0);
+ });
+}, false);
+
+</script>
+<script src=""
+</body>
+</html>
Deleted: trunk/LayoutTests/fast/history/page-cache-webdatabase-opened-db-expected.txt (181576 => 181577)
--- trunk/LayoutTests/fast/history/page-cache-webdatabase-opened-db-expected.txt 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/LayoutTests/fast/history/page-cache-webdatabase-opened-db-expected.txt 2015-03-16 20:20:27 UTC (rev 181577)
@@ -1,11 +0,0 @@
-Tests that a page with an open WebDatabase does not go into the page cache.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-pageshow - not from cache
-PASS Page was not restored from page cache
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
Deleted: trunk/LayoutTests/fast/history/page-cache-webdatabase-opened-db.html (181576 => 181577)
--- trunk/LayoutTests/fast/history/page-cache-webdatabase-opened-db.html 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/LayoutTests/fast/history/page-cache-webdatabase-opened-db.html 2015-03-16 20:20:27 UTC (rev 181577)
@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<script src=""
-<script>
-description('Tests that a page with an open WebDatabase does not go into the page cache.');
-window.jsTestIsAsync = true;
-
-if (window.testRunner) {
- testRunner.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
- testRunner.clearAllDatabases();
-}
-
-window.addEventListener("pageshow", function(event) {
- debug("pageshow - " + (event.persisted ? "" : "not ") + "from cache");
- if (!window.sessionStorage.page_cache_open_webdatabase_test_started)
- return;
-
- delete window.sessionStorage.page_cache_open_webdatabase_test_started;
-
- if (event.persisted)
- testFailed("Page did enter and was restored from the page cache");
- else
- testPassed("Page was not restored from page cache");
- finishJSTest();
-}, false);
-
-window.addEventListener("pagehide", function(event) {
- debug("pagehide - " + (event.persisted ? "" : "not ") + "entering cache");
- if (event.persisted) {
- testFailed("Page entered the page cache.");
- finishJSTest();
- }
-}, false);
-
-window.addEventListener('load', function() {
- // Open the database.
- db = openDatabase("PageCacheTest", "", "Page Cache Test", 10, function (createdDb) {
- // Force a back navigation back to this page.
- window.sessionStorage.page_cache_open_webdatabase_test_started = true;
- window.location.href = ""
- });
-}, false);
-
-</script>
-<script src=""
-</body>
-</html>
Copied: trunk/LayoutTests/fast/history/page-cache-webdatabase-pending-transaction-expected.txt (from rev 181576, trunk/LayoutTests/fast/history/page-cache-webdatabase-opened-db-expected.txt) (0 => 181577)
--- trunk/LayoutTests/fast/history/page-cache-webdatabase-pending-transaction-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/history/page-cache-webdatabase-pending-transaction-expected.txt 2015-03-16 20:20:27 UTC (rev 181577)
@@ -0,0 +1,11 @@
+Tests that a page with an open WebDatabase that has pending transactions does not go into the page cache.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+pageshow - not from cache
+PASS Page was not restored from page cache
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Copied: trunk/LayoutTests/fast/history/page-cache-webdatabase-pending-transaction.html (from rev 181576, trunk/LayoutTests/fast/history/page-cache-webdatabase-opened-db.html) (0 => 181577)
--- trunk/LayoutTests/fast/history/page-cache-webdatabase-pending-transaction.html (rev 0)
+++ trunk/LayoutTests/fast/history/page-cache-webdatabase-pending-transaction.html 2015-03-16 20:20:27 UTC (rev 181577)
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description('Tests that a page with an open WebDatabase that has pending transactions does not go into the page cache.');
+window.jsTestIsAsync = true;
+
+if (window.testRunner) {
+ testRunner.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
+ testRunner.clearAllDatabases();
+}
+
+window.addEventListener("pageshow", function(event) {
+ debug("pageshow - " + (event.persisted ? "" : "not ") + "from cache");
+ if (!window.sessionStorage.page_cache_open_webdatabase_test_started)
+ return;
+
+ delete window.sessionStorage.page_cache_open_webdatabase_test_started;
+
+ if (event.persisted)
+ testFailed("Page did enter and was restored from the page cache");
+ else
+ testPassed("Page was not restored from page cache");
+ finishJSTest();
+}, false);
+
+window.addEventListener("pagehide", function(event) {
+ debug("pagehide - " + (event.persisted ? "" : "not ") + "entering cache");
+ if (event.persisted) {
+ testFailed("Page entered the page cache.");
+ finishJSTest();
+ }
+}, false);
+
+window.addEventListener('load', function() {
+ // Open the database.
+ db = openDatabase("PageCacheTest", "", "Page Cache Test", 32768);
+
+ db.transaction(function(tx) {
+ // Force a back navigation back to this page.
+ window.sessionStorage.page_cache_open_webdatabase_test_started = true;
+ window.location.href = ""
+
+ tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
+ });
+
+ db.transaction(function(tx) {
+ tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS2 (id unique, log)');
+ });
+
+ db.transaction(function(tx) {
+ tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS3 (id unique, log)');
+ });
+}, false);
+
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (181576 => 181577)
--- trunk/Source/WebCore/ChangeLog 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/Source/WebCore/ChangeLog 2015-03-16 20:20:27 UTC (rev 181577)
@@ -1,3 +1,36 @@
+2015-03-16 Chris Dumez <cdu...@apple.com>
+
+ Make DatabaseContext suspendable if there is no pending database activity
+ https://bugs.webkit.org/show_bug.cgi?id=142716
+ <rdar://problem/19923085>
+
+ Reviewed by Andreas Kling.
+
+ Make DatabaseContext suspendable if there is no pending database
+ activity, i.e:
+ - No pending Database creation JS callback
+ - No pending transaction(s)
+
+ Suspending is safe in this case because we are not going to interrupt
+ any database activity, nor fire any JS event.
+
+ This greatly increases the likelihood of pages using websql to enter
+ the PageCache.
+
+ Tests: fast/history/page-cache-webdatabase-no-transaction-db.html
+ fast/history/page-cache-webdatabase-pending-transaction.html
+
+ * Modules/webdatabase/Database.cpp:
+ (WebCore::Database::hasPendingTransaction):
+ * Modules/webdatabase/Database.h:
+ * Modules/webdatabase/DatabaseContext.cpp:
+ (WebCore::DatabaseContext::canSuspend):
+ * Modules/webdatabase/DatabaseManager.cpp:
+ (WebCore::DatabaseManager::openDatabase):
+ * Modules/webdatabase/DatabaseThread.cpp:
+ (WebCore::DatabaseThread::hasPendingDatabaseActivity):
+ * Modules/webdatabase/DatabaseThread.h:
+
2015-03-16 Brady Eidson <beid...@apple.com>
Addressing additional review feedback after http://trac.webkit.org/changeset/181565
Modified: trunk/Source/WebCore/Modules/webdatabase/Database.cpp (181576 => 181577)
--- trunk/Source/WebCore/Modules/webdatabase/Database.cpp 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/Source/WebCore/Modules/webdatabase/Database.cpp 2015-03-16 20:20:27 UTC (rev 181577)
@@ -207,6 +207,12 @@
scheduleTransaction();
}
+bool Database::hasPendingTransaction()
+{
+ MutexLocker locker(m_transactionInProgressMutex);
+ return m_transactionInProgress || !m_transactionQueue.isEmpty();
+}
+
SQLTransactionClient* Database::transactionClient() const
{
return databaseContext()->databaseThread()->transactionClient();
Modified: trunk/Source/WebCore/Modules/webdatabase/Database.h (181576 => 181577)
--- trunk/Source/WebCore/Modules/webdatabase/Database.h 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/Source/WebCore/Modules/webdatabase/Database.h 2015-03-16 20:20:27 UTC (rev 181577)
@@ -58,6 +58,11 @@
void scheduleTransactionStep(SQLTransactionBackend*);
void inProgressTransactionCompleted();
+ bool hasPendingTransaction();
+
+ bool hasPendingCreationEvent() const { return m_hasPendingCreationEvent; }
+ void setHasPendingCreationEvent(bool value) { m_hasPendingCreationEvent = value; }
+
SQLTransactionClient* transactionClient() const;
SQLTransactionCoordinator* transactionCoordinator() const;
@@ -105,6 +110,7 @@
RefPtr<DatabaseContext> m_databaseContext;
bool m_deleted;
+ bool m_hasPendingCreationEvent { false };
friend class DatabaseManager;
friend class DatabaseServer; // FIXME: remove this when the backend has been split out.
Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseContext.cpp (181576 => 181577)
--- trunk/Source/WebCore/Modules/webdatabase/DatabaseContext.cpp 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseContext.cpp 2015-03-16 20:20:27 UTC (rev 181577)
@@ -147,7 +147,10 @@
bool DatabaseContext::canSuspend() const
{
- return !hasOpenDatabases();
+ if (!hasOpenDatabases() || !m_databaseThread)
+ return true;
+
+ return !m_databaseThread->hasPendingDatabaseActivity();
}
DatabaseThread* DatabaseContext::databaseThread()
Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp (181576 => 181577)
--- trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp 2015-03-16 20:20:27 UTC (rev 181577)
@@ -294,8 +294,10 @@
if (backend->isNew() && creationCallback.get()) {
LOG(StorageAPI, "Scheduling DatabaseCreationCallbackTask for database %p\n", database.get());
+ database->setHasPendingCreationEvent(true);
database->m_scriptExecutionContext->postTask([creationCallback, database] (ScriptExecutionContext&) {
creationCallback->handleEvent(database.get());
+ database->setHasPendingCreationEvent(false);
});
}
Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp (181576 => 181577)
--- trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp 2015-03-16 20:20:27 UTC (rev 181577)
@@ -263,4 +263,14 @@
SameDatabasePredicate predicate(database);
m_queue.removeIf(predicate);
}
+
+bool DatabaseThread::hasPendingDatabaseActivity() const
+{
+ for (auto& database : m_openDatabaseSet) {
+ if (database->hasPendingCreationEvent() || database->hasPendingTransaction())
+ return true;
+ }
+ return false;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.h (181576 => 181577)
--- trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.h 2015-03-16 20:06:42 UTC (rev 181576)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.h 2015-03-16 20:20:27 UTC (rev 181577)
@@ -57,6 +57,7 @@
void scheduleTask(std::unique_ptr<DatabaseTask>);
void scheduleImmediateTask(std::unique_ptr<DatabaseTask>); // This just adds the task to the front of the queue - the caller needs to be extremely careful not to create deadlocks when waiting for completion.
void unscheduleDatabaseTasks(Database*);
+ bool hasPendingDatabaseActivity() const;
void recordDatabaseOpen(Database*);
void recordDatabaseClosed(Database*);