<!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>[194263] trunk/Source/WebCore</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/194263">194263</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2015-12-17 23:06:11 -0800 (Thu, 17 Dec 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Modern IDB: Refactor open/delete requests to exist in the same queue.
https://bugs.webkit.org/show_bug.cgi?id=152397

Reviewed by Alex Christensen.

No new tests (Refactor, all existing tests continue to pass).

The order between incoming open and delete requests matters, and each request
needs to be handled individually.

This patch does the above without changing behavior on existing passing tests,
while moving many currently skipped tests closer to passing.

* Modules/indexeddb/server/IDBServerOperation.cpp:
(WebCore::IDBServer::IDBServerOperation::notifyDeleteRequestBlocked):
(WebCore::IDBServer::IDBServerOperation::notifyDidDeleteDatabase):
* Modules/indexeddb/server/IDBServerOperation.h:
(WebCore::IDBServer::IDBServerOperation::hasNotifiedDeleteRequestBlocked):

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase):
(WebCore::IDBServer::UniqueIDBDatabase::openDatabaseConnection):
(WebCore::IDBServer::UniqueIDBDatabase::isVersionChangeInProgress):
(WebCore::IDBServer::UniqueIDBDatabase::performCurrentOpenOperation):
(WebCore::IDBServer::UniqueIDBDatabase::performCurrentDeleteOperation):
(WebCore::IDBServer::UniqueIDBDatabase::handleDatabaseOperations):
(WebCore::IDBServer::UniqueIDBDatabase::handleCurrentOperation):
(WebCore::IDBServer::UniqueIDBDatabase::handleDelete):
(WebCore::IDBServer::UniqueIDBDatabase::invokeOperationAndTransactionTimer):
(WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired):
(WebCore::IDBServer::UniqueIDBDatabase::maybeDeleteDatabase): Deleted.
* Modules/indexeddb/server/UniqueIDBDatabase.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBServerOperationcpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBServerOperationh">trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (194262 => 194263)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-12-18 06:50:02 UTC (rev 194262)
+++ trunk/Source/WebCore/ChangeLog        2015-12-18 07:06:11 UTC (rev 194263)
</span><span class="lines">@@ -1,3 +1,38 @@
</span><ins>+2015-12-17  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB: Refactor open/delete requests to exist in the same queue.
+        https://bugs.webkit.org/show_bug.cgi?id=152397
+
+        Reviewed by Alex Christensen.
+
+        No new tests (Refactor, all existing tests continue to pass).
+
+        The order between incoming open and delete requests matters, and each request
+        needs to be handled individually.
+        
+        This patch does the above without changing behavior on existing passing tests,
+        while moving many currently skipped tests closer to passing.
+    
+        * Modules/indexeddb/server/IDBServerOperation.cpp:
+        (WebCore::IDBServer::IDBServerOperation::notifyDeleteRequestBlocked):
+        (WebCore::IDBServer::IDBServerOperation::notifyDidDeleteDatabase):
+        * Modules/indexeddb/server/IDBServerOperation.h:
+        (WebCore::IDBServer::IDBServerOperation::hasNotifiedDeleteRequestBlocked):
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase):
+        (WebCore::IDBServer::UniqueIDBDatabase::openDatabaseConnection):
+        (WebCore::IDBServer::UniqueIDBDatabase::isVersionChangeInProgress):
+        (WebCore::IDBServer::UniqueIDBDatabase::performCurrentOpenOperation):
+        (WebCore::IDBServer::UniqueIDBDatabase::performCurrentDeleteOperation):
+        (WebCore::IDBServer::UniqueIDBDatabase::handleDatabaseOperations):
+        (WebCore::IDBServer::UniqueIDBDatabase::handleCurrentOperation):
+        (WebCore::IDBServer::UniqueIDBDatabase::handleDelete):
+        (WebCore::IDBServer::UniqueIDBDatabase::invokeOperationAndTransactionTimer):
+        (WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired):
+        (WebCore::IDBServer::UniqueIDBDatabase::maybeDeleteDatabase): Deleted.
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
</ins><span class="cx"> 2015-12-17  Csaba Osztrogonác  &lt;ossy@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [EFL] edje shouldn't have verbose output
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServerOperationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.cpp (194262 => 194263)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.cpp        2015-12-18 06:50:02 UTC (rev 194262)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.cpp        2015-12-18 07:06:11 UTC (rev 194263)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><ins>+#include &quot;IDBResultData.h&quot;
</ins><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -54,6 +55,22 @@
</span><span class="cx">     return m_requestData.isDeleteRequest();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void IDBServerOperation::notifyDeleteRequestBlocked(uint64_t currentVersion)
+{
+    ASSERT(isDeleteRequest());
+    ASSERT(!m_notifiedDeleteRequestBlocked);
+
+    m_connection.notifyOpenDBRequestBlocked(m_requestData.requestIdentifier(), currentVersion, 0);
+    m_notifiedDeleteRequestBlocked = true;
+}
+
+void IDBServerOperation::notifyDidDeleteDatabase(const IDBDatabaseInfo&amp; info)
+{
+    ASSERT(isDeleteRequest());
+
+    m_connection.didDeleteDatabase(IDBResultData::deleteDatabaseSuccess(m_requestData.requestIdentifier(), info));
+}
+
</ins><span class="cx"> } // namespace IDBServer
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServerOperationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.h (194262 => 194263)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.h        2015-12-18 06:50:02 UTC (rev 194262)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServerOperation.h        2015-12-18 07:06:11 UTC (rev 194263)
</span><span class="lines">@@ -34,6 +34,9 @@
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><ins>+
+class IDBDatabaseInfo;
+
</ins><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><span class="cx"> class IDBServerOperation : public RefCounted&lt;IDBServerOperation&gt; {
</span><span class="lines">@@ -46,11 +49,17 @@
</span><span class="cx">     bool isOpenRequest() const;
</span><span class="cx">     bool isDeleteRequest() const;
</span><span class="cx"> 
</span><ins>+    void notifyDeleteRequestBlocked(uint64_t currentVersion);
+    void notifyDidDeleteDatabase(const IDBDatabaseInfo&amp;);
+    bool hasNotifiedDeleteRequestBlocked() const { return m_notifiedDeleteRequestBlocked; }
+
</ins><span class="cx"> private:
</span><span class="cx">     IDBServerOperation(IDBConnectionToClient&amp;, const IDBRequestData&amp;);
</span><span class="cx"> 
</span><span class="cx">     IDBConnectionToClient&amp; m_connection;
</span><span class="cx">     IDBRequestData m_requestData;
</span><ins>+
+    bool m_notifiedDeleteRequestBlocked { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBServer
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (194262 => 194263)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2015-12-18 06:50:02 UTC (rev 194262)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2015-12-18 07:06:11 UTC (rev 194263)
</span><span class="lines">@@ -51,6 +51,15 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+UniqueIDBDatabase::~UniqueIDBDatabase()
+{
+    LOG(IndexedDB, &quot;UniqueIDBDatabase::~UniqueIDBDatabase() (%p)&quot;, this);
+    ASSERT(!hasAnyPendingCallbacks());
+    ASSERT(m_inProgressTransactions.isEmpty());
+    ASSERT(m_pendingTransactions.isEmpty());
+    ASSERT(m_openDatabaseConnections.isEmpty());
+}
+
</ins><span class="cx"> const IDBDatabaseInfo&amp; UniqueIDBDatabase::info() const
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(m_databaseInfo);
</span><span class="lines">@@ -60,9 +69,9 @@
</span><span class="cx"> void UniqueIDBDatabase::openDatabaseConnection(IDBConnectionToClient&amp; connection, const IDBRequestData&amp; requestData)
</span><span class="cx"> {
</span><span class="cx">     auto operation = IDBServerOperation::create(connection, requestData);
</span><del>-    m_pendingOpenDatabaseOperations.append(WTF::move(operation));
</del><ins>+    m_pendingDatabaseOperations.append(WTF::move(operation));
</ins><span class="cx"> 
</span><del>-    // An open operation is already in progress, so this one has to wait.
</del><ins>+    // An open operation is already in progress, so we can't possibly handle this one yet.
</ins><span class="cx">     if (m_isOpeningBackingStore)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -83,39 +92,14 @@
</span><span class="cx">         || !m_countCallbacks.isEmpty();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool UniqueIDBDatabase::maybeDeleteDatabase(IDBServerOperation* newestDeleteOperation)
</del><ins>+bool UniqueIDBDatabase::isVersionChangeInProgress()
</ins><span class="cx"> {
</span><del>-    ASSERT(isMainThread());
-    LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::maybeDeleteDatabase&quot;);
</del><ins>+#ifndef NDEBUG
+    if (m_versionChangeTransaction)
+        ASSERT(m_versionChangeDatabaseConnection);
+#endif
</ins><span class="cx"> 
</span><del>-    if (hasAnyOpenConnections() || !m_closePendingDatabaseConnections.isEmpty()) {
-        // Exactly once, notify all open connections of the pending deletion.
-        if (!m_hasNotifiedConnectionsOfDelete) {
-            notifyConnectionsOfVersionChange(0);
-            m_hasNotifiedConnectionsOfDelete = true;
-        }
-
-        if (newestDeleteOperation)
-            newestDeleteOperation-&gt;connection().notifyOpenDBRequestBlocked(newestDeleteOperation-&gt;requestData().requestIdentifier(), m_databaseInfo-&gt;version(), 0);
-
-        return false;
-    }
-
-    ASSERT(!hasAnyPendingCallbacks());
-    ASSERT(m_inProgressTransactions.isEmpty());
-    ASSERT(m_pendingTransactions.isEmpty());
-    ASSERT(m_openDatabaseConnections.isEmpty());
-    ASSERT(m_pendingOpenDatabaseOperations.isEmpty());
-
-    for (auto&amp; operation : m_pendingDeleteDatabaseOperations) {
-        ASSERT(m_databaseInfo);
-        ASSERT(operation-&gt;isDeleteRequest());
-        operation-&gt;connection().didDeleteDatabase(IDBResultData::deleteDatabaseSuccess(operation-&gt;requestData().requestIdentifier(), *m_databaseInfo));
-    }
-
-    m_server.deleteUniqueIDBDatabase(*this);
-
-    return true;
</del><ins>+    return m_versionChangeDatabaseConnection;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UniqueIDBDatabase::performCurrentOpenOperation()
</span><span class="lines">@@ -125,6 +109,14 @@
</span><span class="cx">     ASSERT(m_currentOperation);
</span><span class="cx">     ASSERT(m_currentOperation-&gt;isOpenRequest());
</span><span class="cx"> 
</span><ins>+    // If we previously started a version change operation but were blocked by having open connections,
+    // we might now be unblocked.
+    if (m_versionChangeDatabaseConnection) {
+        if (!m_versionChangeTransaction &amp;&amp; !hasAnyOpenConnections())
+            startVersionChangeTransaction();
+        return;
+    }
+
</ins><span class="cx">     // 3.3.1 Opening a database
</span><span class="cx">     // If requested version is undefined, then let requested version be 1 if db was created in the previous step,
</span><span class="cx">     // or the current version of db otherwise.
</span><span class="lines">@@ -176,36 +168,77 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::performCurrentDeleteOperation&quot;);
</span><span class="cx"> 
</span><del>-    // Not used yet.
</del><ins>+    ASSERT(m_databaseInfo);
+    ASSERT(m_currentOperation);
+    ASSERT(m_currentOperation-&gt;isDeleteRequest());
+
+    if (hasAnyOpenConnections()) {
+        // Exactly once, notify all open connections of the pending deletion.
+        if (!m_hasNotifiedConnectionsOfDelete) {
+            notifyConnectionsOfVersionChange(0);
+            m_hasNotifiedConnectionsOfDelete = true;
+        }
+
+        if (!m_currentOperation-&gt;hasNotifiedDeleteRequestBlocked())
+            m_currentOperation-&gt;notifyDeleteRequestBlocked(m_databaseInfo-&gt;version());
+
+        return;
+    }
+
+    ASSERT(!hasAnyPendingCallbacks());
+    ASSERT(m_inProgressTransactions.isEmpty());
+    ASSERT(m_pendingTransactions.isEmpty());
+    ASSERT(m_openDatabaseConnections.isEmpty());
+
+    m_currentOperation-&gt;notifyDidDeleteDatabase(*m_databaseInfo);
+    m_currentOperation = nullptr;
+    m_hasNotifiedConnectionsOfDelete = false;
+    m_deletePending = false;
+
+    if (m_pendingDatabaseOperations.isEmpty())
+        m_server.deleteUniqueIDBDatabase(*this);
+    else
+        invokeOperationAndTransactionTimer();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UniqueIDBDatabase::handleDatabaseOperations()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><del>-    LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::handleDatabaseOperations&quot;);
</del><ins>+    LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::handleDatabaseOperations - There are %zu pending&quot;, m_pendingDatabaseOperations.size());
</ins><span class="cx"> 
</span><del>-    // If a version change transaction is currently in progress, no new connections can be opened right now.
-    // We will try again later.
-    if (m_versionChangeDatabaseConnection)
</del><ins>+    if (m_pendingDatabaseOperations.isEmpty())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (m_pendingOpenDatabaseOperations.isEmpty())
-        return;
</del><ins>+    if (m_versionChangeDatabaseConnection || m_currentOperation) {
+        // We can't start the next database operation quite yet, but we might need to notify all open connections
+        // about a pending delete.
+        if (m_pendingDatabaseOperations.first()-&gt;isDeleteRequest() &amp;&amp; !m_hasNotifiedConnectionsOfDelete) {
+            m_hasNotifiedConnectionsOfDelete = true;
+            notifyConnectionsOfVersionChange(0);
+        }
+    }
</ins><span class="cx"> 
</span><del>-    if (m_currentOperation)
-        return;
</del><ins>+    m_currentOperation = m_pendingDatabaseOperations.takeFirst();
+    LOG(IndexedDB, &quot;UniqueIDBDatabase::handleDatabaseOperations - Popped an operation, now there are %zu pending&quot;, m_pendingDatabaseOperations.size());
</ins><span class="cx"> 
</span><del>-    m_currentOperation = m_pendingOpenDatabaseOperations.takeFirst();
</del><ins>+    handleCurrentOperation();
+}
</ins><span class="cx"> 
</span><del>-    // FIXME: Once handleDatabaseOperations also handles delete operations, remove this ASSERT.
-    ASSERT(m_currentOperation-&gt;isOpenRequest());
</del><ins>+void UniqueIDBDatabase::handleCurrentOperation()
+{
+    ASSERT(m_currentOperation);
</ins><span class="cx"> 
</span><ins>+    RefPtr&lt;UniqueIDBDatabase&gt; protector(this);
+
</ins><span class="cx">     if (m_currentOperation-&gt;isOpenRequest())
</span><span class="cx">         performCurrentOpenOperation();
</span><span class="cx">     else if (m_currentOperation-&gt;isDeleteRequest())
</span><span class="cx">         performCurrentDeleteOperation();
</span><span class="cx">     else
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><ins>+
+    if (!m_currentOperation)
+        invokeOperationAndTransactionTimer();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool UniqueIDBDatabase::hasAnyOpenConnections() const
</span><span class="lines">@@ -256,18 +289,8 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::handleDelete&quot;);
</span><span class="cx"> 
</span><del>-    auto operation = IDBServerOperation::create(connection, requestData);
-    auto* rawOperation = &amp;operation.get();
-    m_pendingDeleteDatabaseOperations.append(WTF::move(operation));
-
-    // If a different request has already come in to delete this database, there's nothing left to do.
-    // A delete is already in progress, and this request will be handled along with all the rest.
-    if (m_deletePending)
-        return;
-
-    m_deletePending = true;
-
-    maybeDeleteDatabase(rawOperation);
</del><ins>+    m_pendingDatabaseOperations.append(IDBServerOperation::create(connection, requestData));
+    handleDatabaseOperations();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UniqueIDBDatabase::startVersionChangeTransaction()
</span><span class="lines">@@ -937,6 +960,7 @@
</span><span class="cx"> 
</span><span class="cx"> void UniqueIDBDatabase::invokeOperationAndTransactionTimer()
</span><span class="cx"> {
</span><ins>+    LOG(IndexedDB, &quot;UniqueIDBDatabase::invokeOperationAndTransactionTimer()&quot;);
</ins><span class="cx">     if (!m_operationAndTransactionTimer.isActive())
</span><span class="cx">         m_operationAndTransactionTimer.startOneShot(0);
</span><span class="cx"> }
</span><span class="lines">@@ -945,18 +969,15 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::operationAndTransactionTimerFired&quot;);
</span><span class="cx"> 
</span><del>-    handleDatabaseOperations();
</del><ins>+    RefPtr&lt;UniqueIDBDatabase&gt; protector(this);
</ins><span class="cx"> 
</span><del>-    if (m_deletePending &amp;&amp; maybeDeleteDatabase(nullptr))
-        return;
</del><ins>+    // The current operation might require multiple attempts to handle, so try to
+    // make further progress on it now.
+    if (m_currentOperation)
+        handleCurrentOperation();
</ins><span class="cx"> 
</span><del>-    // If the database was not deleted in the previous step, try to run a transaction now.
-    if (m_pendingTransactions.isEmpty()) {
-        if (!hasAnyOpenConnections() &amp;&amp; m_currentOperation) {
-            startVersionChangeTransaction();
-            return;
-        }
-    }
</del><ins>+    if (!m_currentOperation)
+        handleDatabaseOperations();
</ins><span class="cx"> 
</span><span class="cx">     bool hadDeferredTransactions = false;
</span><span class="cx">     auto transaction = takeNextRunnableTransaction(hadDeferredTransactions);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (194262 => 194263)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h        2015-12-18 06:50:02 UTC (rev 194262)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h        2015-12-18 07:06:11 UTC (rev 194263)
</span><span class="lines">@@ -71,6 +71,8 @@
</span><span class="cx">         return adoptRef(*new UniqueIDBDatabase(server, identifier));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ~UniqueIDBDatabase();
+
</ins><span class="cx">     void openDatabaseConnection(IDBConnectionToClient&amp;, const IDBRequestData&amp;);
</span><span class="cx"> 
</span><span class="cx">     const IDBDatabaseInfo&amp; info() const;
</span><span class="lines">@@ -105,15 +107,16 @@
</span><span class="cx">     UniqueIDBDatabase(IDBServer&amp;, const IDBDatabaseIdentifier&amp;);
</span><span class="cx">     
</span><span class="cx">     void handleDatabaseOperations();
</span><ins>+    void handleCurrentOperation();
</ins><span class="cx">     void performCurrentOpenOperation();
</span><span class="cx">     void performCurrentDeleteOperation();
</span><span class="cx">     void addOpenDatabaseConnection(Ref&lt;UniqueIDBDatabaseConnection&gt;&amp;&amp;);
</span><del>-    bool maybeDeleteDatabase(IDBServerOperation*);
</del><span class="cx">     bool hasAnyOpenConnections() const;
</span><span class="cx"> 
</span><span class="cx">     void startVersionChangeTransaction();
</span><span class="cx">     void notifyConnectionsOfVersionChangeForUpgrade();
</span><span class="cx">     void notifyConnectionsOfVersionChange(uint64_t requestedVersion);
</span><ins>+    bool isVersionChangeInProgress();
</ins><span class="cx"> 
</span><span class="cx">     void activateTransactionInBackingStore(UniqueIDBDatabaseTransaction&amp;);
</span><span class="cx">     void inProgressTransactionCompleted(const IDBResourceIdentifier&amp;);
</span><span class="lines">@@ -173,8 +176,7 @@
</span><span class="cx">     IDBServer&amp; m_server;
</span><span class="cx">     IDBDatabaseIdentifier m_identifier;
</span><span class="cx">     
</span><del>-    Deque&lt;Ref&lt;IDBServerOperation&gt;&gt; m_pendingOpenDatabaseOperations;
-    Deque&lt;Ref&lt;IDBServerOperation&gt;&gt; m_pendingDeleteDatabaseOperations;
</del><ins>+    Deque&lt;Ref&lt;IDBServerOperation&gt;&gt; m_pendingDatabaseOperations;
</ins><span class="cx">     RefPtr&lt;IDBServerOperation&gt; m_currentOperation;
</span><span class="cx"> 
</span><span class="cx">     HashSet&lt;RefPtr&lt;UniqueIDBDatabaseConnection&gt;&gt; m_openDatabaseConnections;
</span></span></pre>
</div>
</div>

</body>
</html>