Title: [181577] trunk
Revision
181577
Author
cdu...@apple.com
Date
2015-03-16 13:20:27 -0700 (Mon, 16 Mar 2015)

Log Message

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.

Source/WebCore:

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:

LayoutTests:

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.

Modified Paths

Added Paths

Removed Paths

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*);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to