Title: [197749] releases/WebKitGTK/webkit-2.12
Revision
197749
Author
carlo...@webkit.org
Date
2016-03-08 01:47:11 -0800 (Tue, 08 Mar 2016)

Log Message

Merge r197474 - Modern IDB: Close UniqueIDBDatabases once they become unused.
https://bugs.webkit.org/show_bug.cgi?id=154922

Reviewed by Alex Christensen.

Source/WebCore:

Tests: storage/indexeddb/modern/256-open-databases.html
       storage/indexeddb/modern/exceed-open-file-limit.html

Without this change, attempts to open a 256th database in the DatabaseProcess will fail on Mac.

Due to SQLite journal files, this limit could come up as early as 128 databases if they are all
in active use.

This is because launchd - by default - limits xpc services to having 256 open file handles by default.

While we should explore raising the limit, we should also close databases we no longer need.

* Modules/indexeddb/server/IDBBackingStore.h:

* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::closeUniqueIDBDatabase):
(WebCore::IDBServer::IDBServer::deleteUniqueIDBDatabase): Deleted.
* Modules/indexeddb/server/IDBServer.h:

* Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp:
(WebCore::IDBServer::MemoryBackingStoreTransaction::MemoryBackingStoreTransaction):

* Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
(WebCore::IDBServer::MemoryIDBBackingStore::getOrEstablishDatabaseInfo):
* Modules/indexeddb/server/MemoryIDBBackingStore.h:

* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::getOrEstablishDatabaseInfo):
* Modules/indexeddb/server/SQLiteIDBBackingStore.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::UniqueIDBDatabase):
(WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase):
(WebCore::IDBServer::UniqueIDBDatabase::performCurrentOpenOperation): Handle the case where opening
  the backing store failed by firing an error event instead of pretending everything is okay.
(WebCore::IDBServer::UniqueIDBDatabase::deleteBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::openBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::didOpenBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::isCurrentlyInUse):
(WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired): If the database is not
  currently in use, close it.
(WebCore::IDBServer::UniqueIDBDatabase::inProgressTransactionCompleted):
* Modules/indexeddb/server/UniqueIDBDatabase.h:
(WebCore::IDBServer::UniqueIDBDatabase::deletePending): Deleted.

* Modules/indexeddb/shared/IDBObjectStoreInfo.cpp:
(WebCore::IDBObjectStoreInfo::isolatedCopy): Actually get this right.

LayoutTests:

* platform/mac-wk1/TestExpectations:
* storage/indexeddb/modern/256-open-databases-expected.txt: Added.
* storage/indexeddb/modern/256-open-databases.html: Added.
* storage/indexeddb/modern/exceed-open-file-limit-expected.txt: Added.
* storage/indexeddb/modern/exceed-open-file-limit.html: Added.
* storage/indexeddb/modern/resources/256-open-databases.js: Added.
* storage/indexeddb/modern/resources/exceed-open-file-limit.js: Added.

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog	2016-03-08 09:47:11 UTC (rev 197749)
@@ -1,3 +1,18 @@
+2016-03-02  Brady Eidson  <beid...@apple.com>
+
+        Modern IDB: Close UniqueIDBDatabases once they become unused.
+        https://bugs.webkit.org/show_bug.cgi?id=154922
+
+        Reviewed by Alex Christensen.
+
+        * platform/mac-wk1/TestExpectations:
+        * storage/indexeddb/modern/256-open-databases-expected.txt: Added.
+        * storage/indexeddb/modern/256-open-databases.html: Added.
+        * storage/indexeddb/modern/exceed-open-file-limit-expected.txt: Added.
+        * storage/indexeddb/modern/exceed-open-file-limit.html: Added.
+        * storage/indexeddb/modern/resources/256-open-databases.js: Added.
+        * storage/indexeddb/modern/resources/exceed-open-file-limit.js: Added.
+
 2016-03-02  Filip Pizlo  <fpi...@apple.com>
 
         Add a benchmark for string transcoding.

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/platform/mac-wk1/TestExpectations (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/platform/mac-wk1/TestExpectations	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/platform/mac-wk1/TestExpectations	2016-03-08 09:47:11 UTC (rev 197749)
@@ -148,6 +148,10 @@
 # This test gives a different output on ElCapitan-wk1 only.
 webkit.org/b/152178 [ Yosemite+ ] fast/replaced/replaced-breaking.html [ Failure ]
 
+# DRT can open way more files than the DatabaseProcess with WebKitTestRunner, and the number is reasonable.
+# So we shouldn't bother with this test in WebKit1.
+storage/indexeddb/modern/exceed-open-file-limit.html
+
 ### END OF (2) Failures without bug reports
 ########################################
 

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases-expected.txt (0 => 197749)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases-expected.txt	2016-03-08 09:47:11 UTC (rev 197749)
@@ -0,0 +1,12 @@
+This test makes sure that if you open 128 unique databases, close your connections to them, and then open 128 other unique databases, that it works.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Opened the first 128 databases. Now closing them...
+Now opening the second 128 databases
+Successfully opened 256 databases (after closing the first 128)
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases.html (0 => 197749)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases.html	2016-03-08 09:47:11 UTC (rev 197749)
@@ -0,0 +1,9 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script src=""
+</body>
+</html>

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit-expected.txt (0 => 197749)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit-expected.txt	2016-03-08 09:47:11 UTC (rev 197749)
@@ -0,0 +1,10 @@
+This test makes sure that script gets an error if too many databases are opened.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Error opening database
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit.html (0 => 197749)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit.html	2016-03-08 09:47:11 UTC (rev 197749)
@@ -0,0 +1,9 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script src=""
+</body>
+</html>

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/256-open-databases.js (0 => 197749)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/256-open-databases.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/256-open-databases.js	2016-03-08 09:47:11 UTC (rev 197749)
@@ -0,0 +1,39 @@
+description("This test makes sure that if you open 128 unique databases, close your connections to them, and then open 128 other unique databases, that it works.");
+
+var databaseConnections = new Array;
+
+for (var i = 0; i < 128; ++i) {
+    var request = window.indexedDB.open("database" + i);
+    request._onerror_ = function() {
+        debug("Unexpected error opening database " + i);
+        finishJSTest();
+    }
+    request._onsuccess_ = function(event) {
+        databaseConnections.push(event.target.result);
+        if (databaseConnections.length == 128)
+            continueTest();
+    }
+}
+
+function continueTest()
+{
+    debug("Opened the first 128 databases. Now closing them...");
+    for (var i = 0; i < 128; ++i)
+        databaseConnections[i].close();
+
+    debug("Now opening the second 128 databases");
+    for (var i = 128; i < 256; ++i) {
+        var request = window.indexedDB.open("database" + i);
+        request._onerror_ = function() {
+            debug("Unexpected error opening database " + i);
+            finishJSTest();
+        }
+        request._onsuccess_ = function(event) {
+            databaseConnections.push(event.target.result);
+            if (databaseConnections.length == 256) {
+                debug("Successfully opened 256 databases (after closing the first 128)");
+                finishJSTest();
+            }
+        }
+    }
+}

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/exceed-open-file-limit.js (0 => 197749)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/exceed-open-file-limit.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/exceed-open-file-limit.js	2016-03-08 09:47:11 UTC (rev 197749)
@@ -0,0 +1,23 @@
+description("This test makes sure that script gets an error if too many databases are opened.");
+
+var databaseConnections = new Array;
+var index = 0;
+
+function openDatabase(index)
+{
+    var request = window.indexedDB.open("database" + index);
+    request._onerror_ = function() {
+        debug("Error opening database");
+        finishJSTest();
+    }
+    request._onsuccess_ = function(event) {
+        databaseConnections.push(event.target.result);
+        if (databaseConnections.length == 100000) {
+            debug("Successfully opened 100000 databases - That should *not* have happened.");
+            finishJSTest();
+        } else
+            openDatabase(++index);
+    } 
+}
+
+openDatabase(index);

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog	2016-03-08 09:47:11 UTC (rev 197749)
@@ -1,3 +1,59 @@
+2016-03-02  Brady Eidson  <beid...@apple.com>
+
+        Modern IDB: Close UniqueIDBDatabases once they become unused.
+        https://bugs.webkit.org/show_bug.cgi?id=154922
+
+        Reviewed by Alex Christensen.
+
+        Tests: storage/indexeddb/modern/256-open-databases.html
+               storage/indexeddb/modern/exceed-open-file-limit.html
+
+        Without this change, attempts to open a 256th database in the DatabaseProcess will fail on Mac.
+        
+        Due to SQLite journal files, this limit could come up as early as 128 databases if they are all
+        in active use.
+        
+        This is because launchd - by default - limits xpc services to having 256 open file handles by default.
+        
+        While we should explore raising the limit, we should also close databases we no longer need.
+        
+        * Modules/indexeddb/server/IDBBackingStore.h:
+
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::closeUniqueIDBDatabase):
+        (WebCore::IDBServer::IDBServer::deleteUniqueIDBDatabase): Deleted.
+        * Modules/indexeddb/server/IDBServer.h:
+
+        * Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp:
+        (WebCore::IDBServer::MemoryBackingStoreTransaction::MemoryBackingStoreTransaction):
+
+        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
+        (WebCore::IDBServer::MemoryIDBBackingStore::getOrEstablishDatabaseInfo):
+        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
+
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+        (WebCore::IDBServer::SQLiteIDBBackingStore::getOrEstablishDatabaseInfo):
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::UniqueIDBDatabase):
+        (WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase):
+        (WebCore::IDBServer::UniqueIDBDatabase::performCurrentOpenOperation): Handle the case where opening
+          the backing store failed by firing an error event instead of pretending everything is okay.
+        (WebCore::IDBServer::UniqueIDBDatabase::deleteBackingStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::openBackingStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::didOpenBackingStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::isCurrentlyInUse):
+        (WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired): If the database is not
+          currently in use, close it.
+        (WebCore::IDBServer::UniqueIDBDatabase::inProgressTransactionCompleted):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+        (WebCore::IDBServer::UniqueIDBDatabase::deletePending): Deleted.
+
+        * Modules/indexeddb/shared/IDBObjectStoreInfo.cpp:
+        (WebCore::IDBObjectStoreInfo::isolatedCopy): Actually get this right.
+
 2016-03-02  Zalan Bujtas  <za...@apple.com>
 
         Use IndentTextOrNot instead of passing isFirstLine/shouldIndentText as bool.

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h	2016-03-08 09:47:11 UTC (rev 197749)
@@ -54,7 +54,7 @@
 public:
     virtual ~IDBBackingStore() { }
 
-    virtual const IDBDatabaseInfo& getOrEstablishDatabaseInfo() = 0;
+    virtual IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&) = 0;
 
     virtual IDBError beginTransaction(const IDBTransactionInfo&) = 0;
     virtual IDBError abortTransaction(const IDBResourceIdentifier& transactionIdentifier) = 0;
@@ -79,7 +79,9 @@
 
     virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) = 0;
     virtual void deleteBackingStore() = 0;
+
     virtual bool supportsSimultaneousTransactions() = 0;
+    virtual bool isEphemeral() = 0;
 };
 
 } // namespace IDBServer

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp	2016-03-08 09:47:11 UTC (rev 197749)
@@ -157,9 +157,9 @@
     database->handleDelete(*connection, requestData);
 }
 
-void IDBServer::deleteUniqueIDBDatabase(UniqueIDBDatabase& database)
+void IDBServer::closeUniqueIDBDatabase(UniqueIDBDatabase& database)
 {
-    LOG(IndexedDB, "IDBServer::deleteUniqueIDBDatabase");
+    LOG(IndexedDB, "IDBServer::closeUniqueIDBDatabase");
 
     auto deletedDatabase = m_uniqueIDBDatabaseMap.take(database.identifier());
     ASSERT_UNUSED(deletedDatabase, deletedDatabase.get() == &database);

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.h (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.h	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.h	2016-03-08 09:47:11 UTC (rev 197749)
@@ -87,7 +87,7 @@
     void registerTransaction(UniqueIDBDatabaseTransaction&);
     void unregisterTransaction(UniqueIDBDatabaseTransaction&);
 
-    void deleteUniqueIDBDatabase(UniqueIDBDatabase&);
+    void closeUniqueIDBDatabase(UniqueIDBDatabase&);
 
     std::unique_ptr<IDBBackingStore> createBackingStore(const IDBDatabaseIdentifier&);
 

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp	2016-03-08 09:47:11 UTC (rev 197749)
@@ -47,8 +47,12 @@
     : m_backingStore(backingStore)
     , m_info(info)
 {
-    if (m_info.mode() == IndexedDB::TransactionMode::VersionChange)
-        m_originalDatabaseInfo = std::make_unique<IDBDatabaseInfo>(m_backingStore.getOrEstablishDatabaseInfo());
+    if (m_info.mode() == IndexedDB::TransactionMode::VersionChange) {
+        IDBDatabaseInfo info;
+        auto error = m_backingStore.getOrEstablishDatabaseInfo(info);
+        if (error.isNull())
+            m_originalDatabaseInfo = std::make_unique<IDBDatabaseInfo>(info);
+    }
 }
 
 MemoryBackingStoreTransaction::~MemoryBackingStoreTransaction()

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp	2016-03-08 09:47:11 UTC (rev 197749)
@@ -55,12 +55,13 @@
 {
 }
 
-const IDBDatabaseInfo& MemoryIDBBackingStore::getOrEstablishDatabaseInfo()
+IDBError MemoryIDBBackingStore::getOrEstablishDatabaseInfo(IDBDatabaseInfo& info)
 {
     if (!m_databaseInfo)
         m_databaseInfo = std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), 0);
 
-    return *m_databaseInfo;
+    info = *m_databaseInfo;
+    return { };
 }
 
 void MemoryIDBBackingStore::setDatabaseInfo(const IDBDatabaseInfo& info)

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h	2016-03-08 09:47:11 UTC (rev 197749)
@@ -46,7 +46,7 @@
     
     virtual ~MemoryIDBBackingStore() override final;
 
-    virtual const IDBDatabaseInfo& getOrEstablishDatabaseInfo() override final;
+    virtual IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&) override final;
     void setDatabaseInfo(const IDBDatabaseInfo&);
 
     virtual IDBError beginTransaction(const IDBTransactionInfo&) override final;
@@ -71,7 +71,9 @@
 
     virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final;
     virtual void deleteBackingStore() override final;
+
     virtual bool supportsSimultaneousTransactions() override final { return true; }
+    virtual bool isEphemeral() override final { return true; }
 
     void removeObjectStoreForVersionChangeAbort(MemoryObjectStore&);
     void restoreObjectStoreForVersionChangeAbort(Ref<MemoryObjectStore>&&);

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp	2016-03-08 09:47:11 UTC (rev 197749)
@@ -557,15 +557,15 @@
     return pathByAppendingComponent(fullDatabaseDirectory(), "IndexedDB.sqlite3");
 }
 
-const IDBDatabaseInfo& SQLiteIDBBackingStore::getOrEstablishDatabaseInfo()
+IDBError SQLiteIDBBackingStore::getOrEstablishDatabaseInfo(IDBDatabaseInfo& info)
 {
     LOG(IndexedDB, "SQLiteIDBBackingStore::getOrEstablishDatabaseInfo - database %s", m_identifier.databaseName().utf8().data());
 
-    if (m_databaseInfo)
-        return *m_databaseInfo;
+    if (m_databaseInfo) {
+        info = *m_databaseInfo;
+        return { };
+    }
 
-    m_databaseInfo = std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), 0);
-
     makeAllDirectories(fullDatabaseDirectory());
     String dbFilename = fullDatabasePath();
 
@@ -576,7 +576,7 @@
     }
 
     if (!m_sqliteDB)
-        return *m_databaseInfo;
+        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to open database file on disk") };
 
     m_sqliteDB->setCollationFunction("IDBKEY", [this](int aLength, const void* a, int bLength, const void* b) {
         return idbKeyCollate(aLength, a, bLength, b);
@@ -585,25 +585,28 @@
     if (!ensureValidRecordsTable()) {
         LOG_ERROR("Error creating or migrating Records table in database");
         m_sqliteDB = nullptr;
-        return *m_databaseInfo;
+        return { IDBDatabaseException::UnknownError, ASCIILiteral("Error creating or migrating Records table in database") };
     }
 
     if (!ensureValidIndexRecordsTable()) {
         LOG_ERROR("Error creating or migrating Index Records table in database");
         m_sqliteDB = nullptr;
-        return *m_databaseInfo;
+        return { IDBDatabaseException::UnknownError, ASCIILiteral("Error creating or migrating Index Records table in database") };
     }
 
     auto databaseInfo = extractExistingDatabaseInfo();
     if (!databaseInfo)
         databaseInfo = createAndPopulateInitialDatabaseInfo();
 
-    if (!databaseInfo)
+    if (!databaseInfo) {
         LOG_ERROR("Unable to establish IDB database at path '%s'", dbFilename.utf8().data());
-    else
-        m_databaseInfo = WTFMove(databaseInfo);
+        m_sqliteDB = nullptr;
+        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to establish IDB database file") };
+    }
 
-    return *m_databaseInfo;
+    m_databaseInfo = WTFMove(databaseInfo);
+    info = *m_databaseInfo;
+    return { };
 }
 
 IDBError SQLiteIDBBackingStore::beginTransaction(const IDBTransactionInfo& info)

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h	2016-03-08 09:47:11 UTC (rev 197749)
@@ -51,7 +51,7 @@
     
     virtual ~SQLiteIDBBackingStore() override final;
 
-    virtual const IDBDatabaseInfo& getOrEstablishDatabaseInfo() override final;
+    virtual IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&) override final;
 
     virtual IDBError beginTransaction(const IDBTransactionInfo&) override final;
     virtual IDBError abortTransaction(const IDBResourceIdentifier& transactionIdentifier) override final;
@@ -75,7 +75,9 @@
 
     virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final;
     virtual void deleteBackingStore() override final;
+
     virtual bool supportsSimultaneousTransactions() override final { return false; }
+    virtual bool isEphemeral() override final { return false; }
 
     void unregisterCursor(SQLiteIDBCursor&);
 

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2016-03-08 09:47:11 UTC (rev 197749)
@@ -50,11 +50,12 @@
     , m_identifier(identifier)
     , m_operationAndTransactionTimer(*this, &UniqueIDBDatabase::operationAndTransactionTimerFired)
 {
+    LOG(IndexedDB, "UniqueIDBDatabase::UniqueIDBDatabase() (%p) %s", this, m_identifier.debugString().utf8().data());
 }
 
 UniqueIDBDatabase::~UniqueIDBDatabase()
 {
-    LOG(IndexedDB, "UniqueIDBDatabase::~UniqueIDBDatabase() (%p)", this);
+    LOG(IndexedDB, "UniqueIDBDatabase::~UniqueIDBDatabase() (%p) %s", this, m_identifier.debugString().utf8().data());
     ASSERT(!hasAnyPendingCallbacks());
     ASSERT(m_inProgressTransactions.isEmpty());
     ASSERT(m_pendingTransactions.isEmpty());
@@ -139,6 +140,14 @@
         return;
     }
 
+    if (!m_backingStoreOpenError.isNull()) {
+        auto result = IDBResultData::error(m_currentOpenDBRequest->requestData().requestIdentifier(), m_backingStoreOpenError);
+        m_currentOpenDBRequest->connection().didOpenDatabase(result);
+        m_currentOpenDBRequest = nullptr;
+
+        return;
+    }
+
     Ref<UniqueIDBDatabaseConnection> connection = UniqueIDBDatabaseConnection::create(*this, m_currentOpenDBRequest->connection());
     UniqueIDBDatabaseConnection* rawConnection = &connection.get();
 
@@ -214,9 +223,15 @@
         m_backingStore->deleteBackingStore();
         m_backingStore = nullptr;
         m_backingStoreSupportsSimultaneousTransactions = false;
+        m_backingStoreIsEphemeral = false;
     } else {
         auto backingStore = m_server.createBackingStore(identifier);
-        auto databaseInfo = backingStore->getOrEstablishDatabaseInfo();
+
+        IDBDatabaseInfo databaseInfo;
+        auto error = backingStore->getOrEstablishDatabaseInfo(databaseInfo);
+        if (!error.isNull())
+            LOG_ERROR("Error getting database info from database %s that we are trying to delete", identifier.debugString().utf8().data());
+
         deletedVersion = databaseInfo.version();
         backingStore->deleteBackingStore();
     }
@@ -248,12 +263,11 @@
     m_currentOpenDBRequest->notifyDidDeleteDatabase(*m_mostRecentDeletedDatabaseInfo);
     m_currentOpenDBRequest = nullptr;
 
-    m_deletePending = false;
     m_deleteBackingStoreInProgress = false;
 
     if (m_closePendingDatabaseConnections.isEmpty()) {
         if (m_pendingOpenDBRequests.isEmpty())
-            m_server.deleteUniqueIDBDatabase(*this);
+            m_server.closeUniqueIDBDatabase(*this);
         else
             invokeOperationAndTransactionTimer();
     }
@@ -464,17 +478,21 @@
     ASSERT(!m_backingStore);
     m_backingStore = m_server.createBackingStore(identifier);
     m_backingStoreSupportsSimultaneousTransactions = m_backingStore->supportsSimultaneousTransactions();
-    auto databaseInfo = m_backingStore->getOrEstablishDatabaseInfo();
+    m_backingStoreIsEphemeral = m_backingStore->isEphemeral();
 
-    m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didOpenBackingStore, databaseInfo));
+    IDBDatabaseInfo databaseInfo;
+    auto error = m_backingStore->getOrEstablishDatabaseInfo(databaseInfo);
+
+    m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didOpenBackingStore, databaseInfo, error));
 }
 
-void UniqueIDBDatabase::didOpenBackingStore(const IDBDatabaseInfo& info)
+void UniqueIDBDatabase::didOpenBackingStore(const IDBDatabaseInfo& info, const IDBError& error)
 {
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::didOpenBackingStore");
     
     m_databaseInfo = std::make_unique<IDBDatabaseInfo>(info);
+    m_backingStoreOpenError = error;
 
     ASSERT(m_isOpeningBackingStore);
     m_isOpeningBackingStore = false;
@@ -1097,6 +1115,11 @@
     invokeOperationAndTransactionTimer();
 }
 
+bool UniqueIDBDatabase::isCurrentlyInUse() const
+{
+    return !m_openDatabaseConnections.isEmpty() || !m_closePendingDatabaseConnections.isEmpty() || !m_pendingOpenDBRequests.isEmpty() || m_currentOpenDBRequest || m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_isOpeningBackingStore || m_deleteBackingStoreInProgress;
+}
+
 void UniqueIDBDatabase::invokeOperationAndTransactionTimer()
 {
     LOG(IndexedDB, "UniqueIDBDatabase::invokeOperationAndTransactionTimer()");
@@ -1110,6 +1133,15 @@
 
     RefPtr<UniqueIDBDatabase> protector(this);
 
+    // This UniqueIDBDatabase might be no longer in use by any web page.
+    // Assuming it is not ephemeral, the server should now close it to free up resources.
+    if (!m_backingStoreIsEphemeral && !isCurrentlyInUse()) {
+        ASSERT(m_pendingTransactions.isEmpty());
+        ASSERT(m_inProgressTransactions.isEmpty());
+        m_server.closeUniqueIDBDatabase(*this);
+        return;
+    }
+
     // The current operation might require multiple attempts to handle, so try to
     // make further progress on it now.
     if (m_currentOpenDBRequest)
@@ -1259,7 +1291,7 @@
     // It's possible that this database had its backing store deleted but there were a few outstanding asynchronous operations.
     // If this transaction completing was the last of those operations, we can finally delete this UniqueIDBDatabase.
     if (m_closePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty() && !m_databaseInfo) {
-        m_server.deleteUniqueIDBDatabase(*this);
+        m_server.closeUniqueIDBDatabase(*this);
         return;
     }
 

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2016-03-08 09:47:11 UTC (rev 197749)
@@ -101,7 +101,6 @@
     void enqueueTransaction(Ref<UniqueIDBDatabaseTransaction>&&);
 
     void handleDelete(IDBConnectionToClient&, const IDBRequestData&);
-    bool deletePending() const { return m_deletePending; }
 
     static JSC::VM& databaseThreadVM();
     static JSC::ExecState& databaseThreadExecState();
@@ -146,7 +145,7 @@
 
     // Main thread callbacks
     void didDeleteBackingStore(uint64_t deletedVersion);
-    void didOpenBackingStore(const IDBDatabaseInfo&);
+    void didOpenBackingStore(const IDBDatabaseInfo&, const IDBError&);
     void didPerformCreateObjectStore(uint64_t callbackIdentifier, const IDBError&, const IDBObjectStoreInfo&);
     void didPerformDeleteObjectStore(uint64_t callbackIdentifier, const IDBError&, uint64_t objectStoreIdentifier);
     void didPerformClearObjectStore(uint64_t callbackIdentifier, const IDBError&);
@@ -173,6 +172,7 @@
     void performCountCallback(uint64_t callbackIdentifier, const IDBError&, uint64_t);
 
     bool hasAnyPendingCallbacks() const;
+    bool isCurrentlyInUse() const;
 
     void invokeOperationAndTransactionTimer();
     void operationAndTransactionTimerFired();
@@ -191,11 +191,13 @@
     RefPtr<UniqueIDBDatabaseTransaction> m_versionChangeTransaction;
 
     bool m_isOpeningBackingStore { false };
+    IDBError m_backingStoreOpenError;
     std::unique_ptr<IDBBackingStore> m_backingStore;
     std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
     std::unique_ptr<IDBDatabaseInfo> m_mostRecentDeletedDatabaseInfo;
 
     bool m_backingStoreSupportsSimultaneousTransactions { false };
+    bool m_backingStoreIsEphemeral { false };
 
     HashMap<uint64_t, ErrorCallback> m_errorCallbacks;
     HashMap<uint64_t, KeyDataCallback> m_keyDataCallbacks;
@@ -212,7 +214,6 @@
     HashCountedSet<uint64_t> m_objectStoreTransactionCounts;
     HashSet<uint64_t> m_objectStoreWriteTransactions;
 
-    bool m_deletePending { false };
     bool m_deleteBackingStoreInProgress { false };
 };
 

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp (197748 => 197749)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp	2016-03-08 09:46:27 UTC (rev 197748)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp	2016-03-08 09:47:11 UTC (rev 197749)
@@ -88,9 +88,14 @@
 {
     IDBObjectStoreInfo result = { m_identifier, m_name.isolatedCopy(), m_keyPath.isolatedCopy(), m_autoIncrement };
 
-    for (auto& iterator : m_indexMap)
+    for (auto& iterator : m_indexMap) {
         result.m_indexMap.set(iterator.key, iterator.value.isolatedCopy());
+        if (iterator.key > result.m_maxIndexID)
+            result.m_maxIndexID = iterator.key;
+    }
 
+    ASSERT(result.m_maxIndexID == m_maxIndexID);
+
     return result;
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to