<!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>[197749] releases/WebKitGTK/webkit-2.12</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/197749">197749</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-03-08 01:47:11 -0800 (Tue, 08 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/197474">r197474</a> - 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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsChangeLog">releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsplatformmacwk1TestExpectations">releases/WebKitGTK/webkit-2.12/LayoutTests/platform/mac-wk1/TestExpectations</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverIDBBackingStoreh">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverIDBServercpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverIDBServerh">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverMemoryBackingStoreTransactioncpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverMemoryIDBBackingStorecpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverMemoryIDBBackingStoreh">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverSQLiteIDBBackingStoreh">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbsharedIDBObjectStoreInfocpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodern256opendatabasesexpectedtxt">releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodern256opendatabaseshtml">releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases.html</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodernexceedopenfilelimitexpectedtxt">releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodernexceedopenfilelimithtml">releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit.html</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodernresources256opendatabasesjs">releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/256-open-databases.js</a></li>
<li><a href="#releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodernresourcesexceedopenfilelimitjs">releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/exceed-open-file-limit.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit212LayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2016-03-02  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        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.
+
</ins><span class="cx"> 2016-03-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add a benchmark for string transcoding.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsplatformmacwk1TestExpectations"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/platform/mac-wk1/TestExpectations (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -148,6 +148,10 @@
</span><span class="cx"> # This test gives a different output on ElCapitan-wk1 only.
</span><span class="cx"> webkit.org/b/152178 [ Yosemite+ ] fast/replaced/replaced-breaking.html [ Failure ]
</span><span class="cx"> 
</span><ins>+# 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
+
</ins><span class="cx"> ### END OF (2) Failures without bug reports
</span><span class="cx"> ########################################
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodern256opendatabasesexpectedtxt"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases-expected.txt (0 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+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 &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+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
+
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodern256opendatabaseshtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/256-open-databases.html (0 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../../resources/js-test.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/shared.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;resources/256-open-databases.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodernexceedopenfilelimitexpectedtxt"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit-expected.txt (0 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+This test makes sure that script gets an error if too many databases are opened.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Error opening database
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodernexceedopenfilelimithtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/exceed-open-file-limit.html (0 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../../resources/js-test.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/shared.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;resources/exceed-open-file-limit.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodernresources256opendatabasesjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/256-open-databases.js (0 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+description(&quot;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.&quot;);
+
+var databaseConnections = new Array;
+
+for (var i = 0; i &lt; 128; ++i) {
+    var request = window.indexedDB.open(&quot;database&quot; + i);
+    request.onerror = function() {
+        debug(&quot;Unexpected error opening database &quot; + i);
+        finishJSTest();
+    }
+    request.onsuccess = function(event) {
+        databaseConnections.push(event.target.result);
+        if (databaseConnections.length == 128)
+            continueTest();
+    }
+}
+
+function continueTest()
+{
+    debug(&quot;Opened the first 128 databases. Now closing them...&quot;);
+    for (var i = 0; i &lt; 128; ++i)
+        databaseConnections[i].close();
+
+    debug(&quot;Now opening the second 128 databases&quot;);
+    for (var i = 128; i &lt; 256; ++i) {
+        var request = window.indexedDB.open(&quot;database&quot; + i);
+        request.onerror = function() {
+            debug(&quot;Unexpected error opening database &quot; + i);
+            finishJSTest();
+        }
+        request.onsuccess = function(event) {
+            databaseConnections.push(event.target.result);
+            if (databaseConnections.length == 256) {
+                debug(&quot;Successfully opened 256 databases (after closing the first 128)&quot;);
+                finishJSTest();
+            }
+        }
+    }
+}
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212LayoutTestsstorageindexeddbmodernresourcesexceedopenfilelimitjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/LayoutTests/storage/indexeddb/modern/resources/exceed-open-file-limit.js (0 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+description(&quot;This test makes sure that script gets an error if too many databases are opened.&quot;);
+
+var databaseConnections = new Array;
+var index = 0;
+
+function openDatabase(index)
+{
+    var request = window.indexedDB.open(&quot;database&quot; + index);
+    request.onerror = function() {
+        debug(&quot;Error opening database&quot;);
+        finishJSTest();
+    }
+    request.onsuccess = function(event) {
+        databaseConnections.push(event.target.result);
+        if (databaseConnections.length == 100000) {
+            debug(&quot;Successfully opened 100000 databases - That should *not* have happened.&quot;);
+            finishJSTest();
+        } else
+            openDatabase(++index);
+    } 
+}
+
+openDatabase(index);
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,59 @@
</span><ins>+2016-03-02  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        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.
+
</ins><span class="cx"> 2016-03-02  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Use IndentTextOrNot instead of passing isFirstLine/shouldIndentText as bool.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx"> public:
</span><span class="cx">     virtual ~IDBBackingStore() { }
</span><span class="cx"> 
</span><del>-    virtual const IDBDatabaseInfo&amp; getOrEstablishDatabaseInfo() = 0;
</del><ins>+    virtual IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&amp;) = 0;
</ins><span class="cx"> 
</span><span class="cx">     virtual IDBError beginTransaction(const IDBTransactionInfo&amp;) = 0;
</span><span class="cx">     virtual IDBError abortTransaction(const IDBResourceIdentifier&amp; transactionIdentifier) = 0;
</span><span class="lines">@@ -79,7 +79,9 @@
</span><span class="cx"> 
</span><span class="cx">     virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) = 0;
</span><span class="cx">     virtual void deleteBackingStore() = 0;
</span><ins>+
</ins><span class="cx">     virtual bool supportsSimultaneousTransactions() = 0;
</span><ins>+    virtual bool isEphemeral() = 0;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBServer
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverIDBServercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -157,9 +157,9 @@
</span><span class="cx">     database-&gt;handleDelete(*connection, requestData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void IDBServer::deleteUniqueIDBDatabase(UniqueIDBDatabase&amp; database)
</del><ins>+void IDBServer::closeUniqueIDBDatabase(UniqueIDBDatabase&amp; database)
</ins><span class="cx"> {
</span><del>-    LOG(IndexedDB, &quot;IDBServer::deleteUniqueIDBDatabase&quot;);
</del><ins>+    LOG(IndexedDB, &quot;IDBServer::closeUniqueIDBDatabase&quot;);
</ins><span class="cx"> 
</span><span class="cx">     auto deletedDatabase = m_uniqueIDBDatabaseMap.take(database.identifier());
</span><span class="cx">     ASSERT_UNUSED(deletedDatabase, deletedDatabase.get() == &amp;database);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverIDBServerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/IDBServer.h (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -87,7 +87,7 @@
</span><span class="cx">     void registerTransaction(UniqueIDBDatabaseTransaction&amp;);
</span><span class="cx">     void unregisterTransaction(UniqueIDBDatabaseTransaction&amp;);
</span><span class="cx"> 
</span><del>-    void deleteUniqueIDBDatabase(UniqueIDBDatabase&amp;);
</del><ins>+    void closeUniqueIDBDatabase(UniqueIDBDatabase&amp;);
</ins><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;IDBBackingStore&gt; createBackingStore(const IDBDatabaseIdentifier&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverMemoryBackingStoreTransactioncpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -47,8 +47,12 @@
</span><span class="cx">     : m_backingStore(backingStore)
</span><span class="cx">     , m_info(info)
</span><span class="cx"> {
</span><del>-    if (m_info.mode() == IndexedDB::TransactionMode::VersionChange)
-        m_originalDatabaseInfo = std::make_unique&lt;IDBDatabaseInfo&gt;(m_backingStore.getOrEstablishDatabaseInfo());
</del><ins>+    if (m_info.mode() == IndexedDB::TransactionMode::VersionChange) {
+        IDBDatabaseInfo info;
+        auto error = m_backingStore.getOrEstablishDatabaseInfo(info);
+        if (error.isNull())
+            m_originalDatabaseInfo = std::make_unique&lt;IDBDatabaseInfo&gt;(info);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> MemoryBackingStoreTransaction::~MemoryBackingStoreTransaction()
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverMemoryIDBBackingStorecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -55,12 +55,13 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const IDBDatabaseInfo&amp; MemoryIDBBackingStore::getOrEstablishDatabaseInfo()
</del><ins>+IDBError MemoryIDBBackingStore::getOrEstablishDatabaseInfo(IDBDatabaseInfo&amp; info)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_databaseInfo)
</span><span class="cx">         m_databaseInfo = std::make_unique&lt;IDBDatabaseInfo&gt;(m_identifier.databaseName(), 0);
</span><span class="cx"> 
</span><del>-    return *m_databaseInfo;
</del><ins>+    info = *m_databaseInfo;
+    return { };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MemoryIDBBackingStore::setDatabaseInfo(const IDBDatabaseInfo&amp; info)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverMemoryIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx">     
</span><span class="cx">     virtual ~MemoryIDBBackingStore() override final;
</span><span class="cx"> 
</span><del>-    virtual const IDBDatabaseInfo&amp; getOrEstablishDatabaseInfo() override final;
</del><ins>+    virtual IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&amp;) override final;
</ins><span class="cx">     void setDatabaseInfo(const IDBDatabaseInfo&amp;);
</span><span class="cx"> 
</span><span class="cx">     virtual IDBError beginTransaction(const IDBTransactionInfo&amp;) override final;
</span><span class="lines">@@ -71,7 +71,9 @@
</span><span class="cx"> 
</span><span class="cx">     virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final;
</span><span class="cx">     virtual void deleteBackingStore() override final;
</span><ins>+
</ins><span class="cx">     virtual bool supportsSimultaneousTransactions() override final { return true; }
</span><ins>+    virtual bool isEphemeral() override final { return true; }
</ins><span class="cx"> 
</span><span class="cx">     void removeObjectStoreForVersionChangeAbort(MemoryObjectStore&amp;);
</span><span class="cx">     void restoreObjectStoreForVersionChangeAbort(Ref&lt;MemoryObjectStore&gt;&amp;&amp;);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -557,15 +557,15 @@
</span><span class="cx">     return pathByAppendingComponent(fullDatabaseDirectory(), &quot;IndexedDB.sqlite3&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const IDBDatabaseInfo&amp; SQLiteIDBBackingStore::getOrEstablishDatabaseInfo()
</del><ins>+IDBError SQLiteIDBBackingStore::getOrEstablishDatabaseInfo(IDBDatabaseInfo&amp; info)
</ins><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;SQLiteIDBBackingStore::getOrEstablishDatabaseInfo - database %s&quot;, m_identifier.databaseName().utf8().data());
</span><span class="cx"> 
</span><del>-    if (m_databaseInfo)
-        return *m_databaseInfo;
</del><ins>+    if (m_databaseInfo) {
+        info = *m_databaseInfo;
+        return { };
+    }
</ins><span class="cx"> 
</span><del>-    m_databaseInfo = std::make_unique&lt;IDBDatabaseInfo&gt;(m_identifier.databaseName(), 0);
-
</del><span class="cx">     makeAllDirectories(fullDatabaseDirectory());
</span><span class="cx">     String dbFilename = fullDatabasePath();
</span><span class="cx"> 
</span><span class="lines">@@ -576,7 +576,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!m_sqliteDB)
</span><del>-        return *m_databaseInfo;
</del><ins>+        return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Unable to open database file on disk&quot;) };
</ins><span class="cx"> 
</span><span class="cx">     m_sqliteDB-&gt;setCollationFunction(&quot;IDBKEY&quot;, [this](int aLength, const void* a, int bLength, const void* b) {
</span><span class="cx">         return idbKeyCollate(aLength, a, bLength, b);
</span><span class="lines">@@ -585,25 +585,28 @@
</span><span class="cx">     if (!ensureValidRecordsTable()) {
</span><span class="cx">         LOG_ERROR(&quot;Error creating or migrating Records table in database&quot;);
</span><span class="cx">         m_sqliteDB = nullptr;
</span><del>-        return *m_databaseInfo;
</del><ins>+        return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Error creating or migrating Records table in database&quot;) };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!ensureValidIndexRecordsTable()) {
</span><span class="cx">         LOG_ERROR(&quot;Error creating or migrating Index Records table in database&quot;);
</span><span class="cx">         m_sqliteDB = nullptr;
</span><del>-        return *m_databaseInfo;
</del><ins>+        return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Error creating or migrating Index Records table in database&quot;) };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     auto databaseInfo = extractExistingDatabaseInfo();
</span><span class="cx">     if (!databaseInfo)
</span><span class="cx">         databaseInfo = createAndPopulateInitialDatabaseInfo();
</span><span class="cx"> 
</span><del>-    if (!databaseInfo)
</del><ins>+    if (!databaseInfo) {
</ins><span class="cx">         LOG_ERROR(&quot;Unable to establish IDB database at path '%s'&quot;, dbFilename.utf8().data());
</span><del>-    else
-        m_databaseInfo = WTFMove(databaseInfo);
</del><ins>+        m_sqliteDB = nullptr;
+        return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Unable to establish IDB database file&quot;) };
+    }
</ins><span class="cx"> 
</span><del>-    return *m_databaseInfo;
</del><ins>+    m_databaseInfo = WTFMove(databaseInfo);
+    info = *m_databaseInfo;
+    return { };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IDBError SQLiteIDBBackingStore::beginTransaction(const IDBTransactionInfo&amp; info)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverSQLiteIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx">     
</span><span class="cx">     virtual ~SQLiteIDBBackingStore() override final;
</span><span class="cx"> 
</span><del>-    virtual const IDBDatabaseInfo&amp; getOrEstablishDatabaseInfo() override final;
</del><ins>+    virtual IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&amp;) override final;
</ins><span class="cx"> 
</span><span class="cx">     virtual IDBError beginTransaction(const IDBTransactionInfo&amp;) override final;
</span><span class="cx">     virtual IDBError abortTransaction(const IDBResourceIdentifier&amp; transactionIdentifier) override final;
</span><span class="lines">@@ -75,7 +75,9 @@
</span><span class="cx"> 
</span><span class="cx">     virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final;
</span><span class="cx">     virtual void deleteBackingStore() override final;
</span><ins>+
</ins><span class="cx">     virtual bool supportsSimultaneousTransactions() override final { return false; }
</span><ins>+    virtual bool isEphemeral() override final { return false; }
</ins><span class="cx"> 
</span><span class="cx">     void unregisterCursor(SQLiteIDBCursor&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -50,11 +50,12 @@
</span><span class="cx">     , m_identifier(identifier)
</span><span class="cx">     , m_operationAndTransactionTimer(*this, &amp;UniqueIDBDatabase::operationAndTransactionTimerFired)
</span><span class="cx"> {
</span><ins>+    LOG(IndexedDB, &quot;UniqueIDBDatabase::UniqueIDBDatabase() (%p) %s&quot;, this, m_identifier.debugString().utf8().data());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> UniqueIDBDatabase::~UniqueIDBDatabase()
</span><span class="cx"> {
</span><del>-    LOG(IndexedDB, &quot;UniqueIDBDatabase::~UniqueIDBDatabase() (%p)&quot;, this);
</del><ins>+    LOG(IndexedDB, &quot;UniqueIDBDatabase::~UniqueIDBDatabase() (%p) %s&quot;, this, m_identifier.debugString().utf8().data());
</ins><span class="cx">     ASSERT(!hasAnyPendingCallbacks());
</span><span class="cx">     ASSERT(m_inProgressTransactions.isEmpty());
</span><span class="cx">     ASSERT(m_pendingTransactions.isEmpty());
</span><span class="lines">@@ -139,6 +140,14 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (!m_backingStoreOpenError.isNull()) {
+        auto result = IDBResultData::error(m_currentOpenDBRequest-&gt;requestData().requestIdentifier(), m_backingStoreOpenError);
+        m_currentOpenDBRequest-&gt;connection().didOpenDatabase(result);
+        m_currentOpenDBRequest = nullptr;
+
+        return;
+    }
+
</ins><span class="cx">     Ref&lt;UniqueIDBDatabaseConnection&gt; connection = UniqueIDBDatabaseConnection::create(*this, m_currentOpenDBRequest-&gt;connection());
</span><span class="cx">     UniqueIDBDatabaseConnection* rawConnection = &amp;connection.get();
</span><span class="cx"> 
</span><span class="lines">@@ -214,9 +223,15 @@
</span><span class="cx">         m_backingStore-&gt;deleteBackingStore();
</span><span class="cx">         m_backingStore = nullptr;
</span><span class="cx">         m_backingStoreSupportsSimultaneousTransactions = false;
</span><ins>+        m_backingStoreIsEphemeral = false;
</ins><span class="cx">     } else {
</span><span class="cx">         auto backingStore = m_server.createBackingStore(identifier);
</span><del>-        auto databaseInfo = backingStore-&gt;getOrEstablishDatabaseInfo();
</del><ins>+
+        IDBDatabaseInfo databaseInfo;
+        auto error = backingStore-&gt;getOrEstablishDatabaseInfo(databaseInfo);
+        if (!error.isNull())
+            LOG_ERROR(&quot;Error getting database info from database %s that we are trying to delete&quot;, identifier.debugString().utf8().data());
+
</ins><span class="cx">         deletedVersion = databaseInfo.version();
</span><span class="cx">         backingStore-&gt;deleteBackingStore();
</span><span class="cx">     }
</span><span class="lines">@@ -248,12 +263,11 @@
</span><span class="cx">     m_currentOpenDBRequest-&gt;notifyDidDeleteDatabase(*m_mostRecentDeletedDatabaseInfo);
</span><span class="cx">     m_currentOpenDBRequest = nullptr;
</span><span class="cx"> 
</span><del>-    m_deletePending = false;
</del><span class="cx">     m_deleteBackingStoreInProgress = false;
</span><span class="cx"> 
</span><span class="cx">     if (m_closePendingDatabaseConnections.isEmpty()) {
</span><span class="cx">         if (m_pendingOpenDBRequests.isEmpty())
</span><del>-            m_server.deleteUniqueIDBDatabase(*this);
</del><ins>+            m_server.closeUniqueIDBDatabase(*this);
</ins><span class="cx">         else
</span><span class="cx">             invokeOperationAndTransactionTimer();
</span><span class="cx">     }
</span><span class="lines">@@ -464,17 +478,21 @@
</span><span class="cx">     ASSERT(!m_backingStore);
</span><span class="cx">     m_backingStore = m_server.createBackingStore(identifier);
</span><span class="cx">     m_backingStoreSupportsSimultaneousTransactions = m_backingStore-&gt;supportsSimultaneousTransactions();
</span><del>-    auto databaseInfo = m_backingStore-&gt;getOrEstablishDatabaseInfo();
</del><ins>+    m_backingStoreIsEphemeral = m_backingStore-&gt;isEphemeral();
</ins><span class="cx"> 
</span><del>-    m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didOpenBackingStore, databaseInfo));
</del><ins>+    IDBDatabaseInfo databaseInfo;
+    auto error = m_backingStore-&gt;getOrEstablishDatabaseInfo(databaseInfo);
+
+    m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didOpenBackingStore, databaseInfo, error));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UniqueIDBDatabase::didOpenBackingStore(const IDBDatabaseInfo&amp; info)
</del><ins>+void UniqueIDBDatabase::didOpenBackingStore(const IDBDatabaseInfo&amp; info, const IDBError&amp; error)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx">     LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::didOpenBackingStore&quot;);
</span><span class="cx">     
</span><span class="cx">     m_databaseInfo = std::make_unique&lt;IDBDatabaseInfo&gt;(info);
</span><ins>+    m_backingStoreOpenError = error;
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(m_isOpeningBackingStore);
</span><span class="cx">     m_isOpeningBackingStore = false;
</span><span class="lines">@@ -1097,6 +1115,11 @@
</span><span class="cx">     invokeOperationAndTransactionTimer();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool UniqueIDBDatabase::isCurrentlyInUse() const
+{
+    return !m_openDatabaseConnections.isEmpty() || !m_closePendingDatabaseConnections.isEmpty() || !m_pendingOpenDBRequests.isEmpty() || m_currentOpenDBRequest || m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_isOpeningBackingStore || m_deleteBackingStoreInProgress;
+}
+
</ins><span class="cx"> void UniqueIDBDatabase::invokeOperationAndTransactionTimer()
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;UniqueIDBDatabase::invokeOperationAndTransactionTimer()&quot;);
</span><span class="lines">@@ -1110,6 +1133,15 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;UniqueIDBDatabase&gt; protector(this);
</span><span class="cx"> 
</span><ins>+    // 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 &amp;&amp; !isCurrentlyInUse()) {
+        ASSERT(m_pendingTransactions.isEmpty());
+        ASSERT(m_inProgressTransactions.isEmpty());
+        m_server.closeUniqueIDBDatabase(*this);
+        return;
+    }
+
</ins><span class="cx">     // The current operation might require multiple attempts to handle, so try to
</span><span class="cx">     // make further progress on it now.
</span><span class="cx">     if (m_currentOpenDBRequest)
</span><span class="lines">@@ -1259,7 +1291,7 @@
</span><span class="cx">     // It's possible that this database had its backing store deleted but there were a few outstanding asynchronous operations.
</span><span class="cx">     // If this transaction completing was the last of those operations, we can finally delete this UniqueIDBDatabase.
</span><span class="cx">     if (m_closePendingDatabaseConnections.isEmpty() &amp;&amp; m_pendingOpenDBRequests.isEmpty() &amp;&amp; !m_databaseInfo) {
</span><del>-        m_server.deleteUniqueIDBDatabase(*this);
</del><ins>+        m_server.closeUniqueIDBDatabase(*this);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -101,7 +101,6 @@
</span><span class="cx">     void enqueueTransaction(Ref&lt;UniqueIDBDatabaseTransaction&gt;&amp;&amp;);
</span><span class="cx"> 
</span><span class="cx">     void handleDelete(IDBConnectionToClient&amp;, const IDBRequestData&amp;);
</span><del>-    bool deletePending() const { return m_deletePending; }
</del><span class="cx"> 
</span><span class="cx">     static JSC::VM&amp; databaseThreadVM();
</span><span class="cx">     static JSC::ExecState&amp; databaseThreadExecState();
</span><span class="lines">@@ -146,7 +145,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Main thread callbacks
</span><span class="cx">     void didDeleteBackingStore(uint64_t deletedVersion);
</span><del>-    void didOpenBackingStore(const IDBDatabaseInfo&amp;);
</del><ins>+    void didOpenBackingStore(const IDBDatabaseInfo&amp;, const IDBError&amp;);
</ins><span class="cx">     void didPerformCreateObjectStore(uint64_t callbackIdentifier, const IDBError&amp;, const IDBObjectStoreInfo&amp;);
</span><span class="cx">     void didPerformDeleteObjectStore(uint64_t callbackIdentifier, const IDBError&amp;, uint64_t objectStoreIdentifier);
</span><span class="cx">     void didPerformClearObjectStore(uint64_t callbackIdentifier, const IDBError&amp;);
</span><span class="lines">@@ -173,6 +172,7 @@
</span><span class="cx">     void performCountCallback(uint64_t callbackIdentifier, const IDBError&amp;, uint64_t);
</span><span class="cx"> 
</span><span class="cx">     bool hasAnyPendingCallbacks() const;
</span><ins>+    bool isCurrentlyInUse() const;
</ins><span class="cx"> 
</span><span class="cx">     void invokeOperationAndTransactionTimer();
</span><span class="cx">     void operationAndTransactionTimerFired();
</span><span class="lines">@@ -191,11 +191,13 @@
</span><span class="cx">     RefPtr&lt;UniqueIDBDatabaseTransaction&gt; m_versionChangeTransaction;
</span><span class="cx"> 
</span><span class="cx">     bool m_isOpeningBackingStore { false };
</span><ins>+    IDBError m_backingStoreOpenError;
</ins><span class="cx">     std::unique_ptr&lt;IDBBackingStore&gt; m_backingStore;
</span><span class="cx">     std::unique_ptr&lt;IDBDatabaseInfo&gt; m_databaseInfo;
</span><span class="cx">     std::unique_ptr&lt;IDBDatabaseInfo&gt; m_mostRecentDeletedDatabaseInfo;
</span><span class="cx"> 
</span><span class="cx">     bool m_backingStoreSupportsSimultaneousTransactions { false };
</span><ins>+    bool m_backingStoreIsEphemeral { false };
</ins><span class="cx"> 
</span><span class="cx">     HashMap&lt;uint64_t, ErrorCallback&gt; m_errorCallbacks;
</span><span class="cx">     HashMap&lt;uint64_t, KeyDataCallback&gt; m_keyDataCallbacks;
</span><span class="lines">@@ -212,7 +214,6 @@
</span><span class="cx">     HashCountedSet&lt;uint64_t&gt; m_objectStoreTransactionCounts;
</span><span class="cx">     HashSet&lt;uint64_t&gt; m_objectStoreWriteTransactions;
</span><span class="cx"> 
</span><del>-    bool m_deletePending { false };
</del><span class="cx">     bool m_deleteBackingStoreInProgress { false };
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreModulesindexeddbsharedIDBObjectStoreInfocpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp (197748 => 197749)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -88,9 +88,14 @@
</span><span class="cx"> {
</span><span class="cx">     IDBObjectStoreInfo result = { m_identifier, m_name.isolatedCopy(), m_keyPath.isolatedCopy(), m_autoIncrement };
</span><span class="cx"> 
</span><del>-    for (auto&amp; iterator : m_indexMap)
</del><ins>+    for (auto&amp; iterator : m_indexMap) {
</ins><span class="cx">         result.m_indexMap.set(iterator.key, iterator.value.isolatedCopy());
</span><ins>+        if (iterator.key &gt; result.m_maxIndexID)
+            result.m_maxIndexID = iterator.key;
+    }
</ins><span class="cx"> 
</span><ins>+    ASSERT(result.m_maxIndexID == m_maxIndexID);
+
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>