<!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>[200322] trunk/Source</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/200322">200322</a></dd>
<dt>Author</dt> <dd>dbates@webkit.org</dd>
<dt>Date</dt> <dd>2016-05-02 08:57:05 -0700 (Mon, 02 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>DatabaseTracker::closeAllDatabases calls Database::close from the wrong thread
https://bugs.webkit.org/show_bug.cgi?id=147672
&lt;rdar://problem/22357464&gt;

Reviewed by Brady Eidson.

Source/WebCore:

Schedule a DatabaseCloseTask when Database::close() is called from a thread other than the
database thread as the database thread is responsible for interacting with the database.

Currently -[WebDatabaseManager startBackgroundTask] and WebProcess::processWillSuspendImminently()
call DatabaseTracker::closeAllDatabases() indirectly and directly, respectively, from a
thread other than the database thread. In a debug build, this causes an assertion failure
in Database::close(). In a release/production build, this starts a race between the calling
thread and the database thread that can lead to a crash. It is the responsibility of the
database thread to manage the database. We should ensure that calling Database::close()
delegates the responsibility of actually closing the database to the database thread to
avoid interfering with the database thread or the need to synchronize access to data
structures used by the database thread.

* Modules/webdatabase/Database.cpp:
(WebCore::Database::interrupt): Added. Turns around and calls SQLiteDatabase::interrupt().
(WebCore::Database::close): Added. Schedules a DatabaseCloseTask to close the database and
wait for it to complete if we have not already scheduled closing the database.
(WebCore::Database::performClose): Renamed; formerly named close.
(WebCore::Database::markAsDeletedAndClose): Extracted logic to schedule a DatabaseCloseTask
from here to Database::close() and modified this function to call Database::close().
* Modules/webdatabase/Database.h:
* Modules/webdatabase/DatabaseTask.cpp:
(WebCore::DatabaseCloseTask::doPerformTask): Call Database::performClose() instead of Database::close()
as the latter has been repurposed to schedule closing the database.
* Modules/webdatabase/DatabaseThread.cpp:
(WebCore::DatabaseThread::databaseThread): Ditto.
* Modules/webdatabase/DatabaseTracker.cpp:
(WebCore::DatabaseTracker::closeAllDatabases): Added argument currentQueryBehavior (defaults
to CurrentQueryBehavior::RunToCompletion - close every database after completion of the
current database query, if any).
* Modules/webdatabase/DatabaseTracker.h:
* platform/sql/SQLiteDatabase.cpp:
(WebCore::SQLiteDatabase::interrupt): Added. This is safe to call regardless of the state
of the database and thread safe by &lt;https://www.sqlite.org/c3ref/interrupt.html&gt;.
* platform/sql/SQLiteDatabase.h:

Source/WebKit/mac:

Update the background assertion expiration callback to call DatabaseTracker::closeAllDatabases()
with CurrentQueryBehavior::Interrupt so that we abort a long running query and close the database
immediately to avoid holding a locked file when the process is suspended.

* Storage/WebDatabaseManager.mm:
(+[WebDatabaseManager startBackgroundTask]):

Source/WebKit2:

Call DatabaseTracker::closeAllDatabases() with CurrentQueryBehavior::Interrupt so that we abort
a long running query and close the database immediately to avoid holding a locked file when the
process is suspended.

* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::processWillSuspendImminently):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabasecpp">trunk/Source/WebCore/Modules/webdatabase/Database.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabaseh">trunk/Source/WebCore/Modules/webdatabase/Database.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabaseTaskcpp">trunk/Source/WebCore/Modules/webdatabase/DatabaseTask.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabaseThreadcpp">trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabaseTrackercpp">trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabaseTrackerh">trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h</a></li>
<li><a href="#trunkSourceWebCoreplatformsqlSQLiteDatabasecpp">trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformsqlSQLiteDatabaseh">trunk/Source/WebCore/platform/sql/SQLiteDatabase.h</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacStorageWebDatabaseManagermm">trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcesscpp">trunk/Source/WebKit2/WebProcess/WebProcess.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebCore/ChangeLog        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -1,3 +1,47 @@
</span><ins>+2016-05-02  Daniel Bates  &lt;dabates@apple.com&gt;
+
+        DatabaseTracker::closeAllDatabases calls Database::close from the wrong thread
+        https://bugs.webkit.org/show_bug.cgi?id=147672
+        &lt;rdar://problem/22357464&gt;
+
+        Reviewed by Brady Eidson.
+
+        Schedule a DatabaseCloseTask when Database::close() is called from a thread other than the
+        database thread as the database thread is responsible for interacting with the database.
+
+        Currently -[WebDatabaseManager startBackgroundTask] and WebProcess::processWillSuspendImminently()
+        call DatabaseTracker::closeAllDatabases() indirectly and directly, respectively, from a
+        thread other than the database thread. In a debug build, this causes an assertion failure
+        in Database::close(). In a release/production build, this starts a race between the calling
+        thread and the database thread that can lead to a crash. It is the responsibility of the
+        database thread to manage the database. We should ensure that calling Database::close()
+        delegates the responsibility of actually closing the database to the database thread to
+        avoid interfering with the database thread or the need to synchronize access to data
+        structures used by the database thread.
+
+        * Modules/webdatabase/Database.cpp:
+        (WebCore::Database::interrupt): Added. Turns around and calls SQLiteDatabase::interrupt().
+        (WebCore::Database::close): Added. Schedules a DatabaseCloseTask to close the database and
+        wait for it to complete if we have not already scheduled closing the database.
+        (WebCore::Database::performClose): Renamed; formerly named close.
+        (WebCore::Database::markAsDeletedAndClose): Extracted logic to schedule a DatabaseCloseTask
+        from here to Database::close() and modified this function to call Database::close().
+        * Modules/webdatabase/Database.h:
+        * Modules/webdatabase/DatabaseTask.cpp:
+        (WebCore::DatabaseCloseTask::doPerformTask): Call Database::performClose() instead of Database::close()
+        as the latter has been repurposed to schedule closing the database.
+        * Modules/webdatabase/DatabaseThread.cpp:
+        (WebCore::DatabaseThread::databaseThread): Ditto.
+        * Modules/webdatabase/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::closeAllDatabases): Added argument currentQueryBehavior (defaults
+        to CurrentQueryBehavior::RunToCompletion - close every database after completion of the
+        current database query, if any).
+        * Modules/webdatabase/DatabaseTracker.h:
+        * platform/sql/SQLiteDatabase.cpp:
+        (WebCore::SQLiteDatabase::interrupt): Added. This is safe to call regardless of the state
+        of the database and thread safe by &lt;https://www.sqlite.org/c3ref/interrupt.html&gt;.
+        * platform/sql/SQLiteDatabase.h:
+
</ins><span class="cx"> 2016-05-02  Yoav Weiss  &lt;yoav@yoav.ws&gt;
</span><span class="cx"> 
</span><span class="cx">         Move ResourceTiming behind a runtime flag
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/Database.cpp (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/Database.cpp        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebCore/Modules/webdatabase/Database.cpp        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -279,8 +279,33 @@
</span><span class="cx">     return success;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Database::interrupt()
+{
+    // It is safe to call this from any thread for an opened or closed database.
+    m_sqliteDatabase.interrupt();
+}
+
</ins><span class="cx"> void Database::close()
</span><span class="cx"> {
</span><ins>+    if (!databaseContext()-&gt;databaseThread())
+        return;
+
+    DatabaseTaskSynchronizer synchronizer;
+    if (databaseContext()-&gt;databaseThread()-&gt;terminationRequested(&amp;synchronizer)) {
+        LOG(StorageAPI, &quot;Database handle %p is on a terminated DatabaseThread, cannot be marked for normal closure\n&quot;, this);
+        return;
+    }
+
+    databaseContext()-&gt;databaseThread()-&gt;scheduleImmediateTask(std::make_unique&lt;DatabaseCloseTask&gt;(*this, synchronizer));
+
+    // FIXME: iOS depends on this function blocking until the database is closed as part
+    // of closing all open databases from a process assertion expiration handler.
+    // See &lt;https://bugs.webkit.org/show_bug.cgi?id=157184&gt;.
+    synchronizer.waitForTaskCompletion();
+}
+
+void Database::performClose()
+{
</ins><span class="cx">     ASSERT(databaseContext()-&gt;databaseThread());
</span><span class="cx">     ASSERT(currentThread() == databaseContext()-&gt;databaseThread()-&gt;getThreadID());
</span><span class="cx"> 
</span><span class="lines">@@ -624,15 +649,7 @@
</span><span class="cx">     LOG(StorageAPI, &quot;Marking %s (%p) as deleted&quot;, stringIdentifier().ascii().data(), this);
</span><span class="cx">     m_deleted = true;
</span><span class="cx"> 
</span><del>-    DatabaseTaskSynchronizer synchronizer;
-    if (databaseContext()-&gt;databaseThread()-&gt;terminationRequested(&amp;synchronizer)) {
-        LOG(StorageAPI, &quot;Database handle %p is on a terminated DatabaseThread, cannot be marked for normal closure\n&quot;, this);
-        return;
-    }
-
-    auto task = std::make_unique&lt;DatabaseCloseTask&gt;(*this, synchronizer);
-    databaseContext()-&gt;databaseThread()-&gt;scheduleImmediateTask(WTFMove(task));
-    synchronizer.waitForTaskCompletion();
</del><ins>+    close();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Database::changeVersion(const String&amp; oldVersion, const String&amp; newVersion, RefPtr&lt;SQLTransactionCallback&gt;&amp;&amp; callback, RefPtr&lt;SQLTransactionErrorCallback&gt;&amp;&amp; errorCallback, RefPtr&lt;VoidCallback&gt;&amp;&amp; successCallback)
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/Database.h (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/Database.h        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebCore/Modules/webdatabase/Database.h        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -59,6 +59,8 @@
</span><span class="cx">     virtual bool openAndVerifyVersion(bool setVersionInNewDatabase, DatabaseError&amp;, String&amp; errorMessage);
</span><span class="cx">     void close();
</span><span class="cx"> 
</span><ins>+    void interrupt();
+
</ins><span class="cx">     bool opened() const { return m_opened; }
</span><span class="cx">     bool isNew() const { return m_new; }
</span><span class="cx"> 
</span><span class="lines">@@ -113,10 +115,14 @@
</span><span class="cx"> 
</span><span class="cx">     void scheduleTransactionCallback(SQLTransaction*);
</span><span class="cx"> 
</span><ins>+    void incrementalVacuumIfNeeded();
+
+    // Called from DatabaseTask
</ins><span class="cx">     bool performOpenAndVerify(bool shouldSetVersionInNewDatabase, DatabaseError&amp;, String&amp; errorMessage);
</span><span class="cx">     Vector&lt;String&gt; performGetTableNames();
</span><span class="cx"> 
</span><del>-    void incrementalVacuumIfNeeded();
</del><ins>+    // Called from DatabaseTask and DatabaseThread
+    void performClose();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     Database(PassRefPtr&lt;DatabaseContext&gt;, const String&amp; name, const String&amp; expectedVersion, const String&amp; displayName, unsigned long estimatedSize);
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabaseTaskcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTask.cpp (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTask.cpp        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTask.cpp        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx"> 
</span><span class="cx"> void DatabaseCloseTask::doPerformTask()
</span><span class="cx"> {
</span><del>-    database().close();
</del><ins>+    database().performClose();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if !LOG_DISABLED
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabaseThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -127,7 +127,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (auto&amp; openDatabase : openSetCopy)
</span><del>-        openDatabase-&gt;close();
</del><ins>+        openDatabase-&gt;performClose();
</ins><span class="cx"> 
</span><span class="cx">     // Detach the thread so its resources are no longer of any concern to anyone else
</span><span class="cx">     detachThread(m_threadID);
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabaseTrackercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -307,7 +307,7 @@
</span><span class="cx">     return maxSize;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DatabaseTracker::closeAllDatabases()
</del><ins>+void DatabaseTracker::closeAllDatabases(CurrentQueryBehavior currentQueryBehavior)
</ins><span class="cx"> {
</span><span class="cx">     Vector&lt;Ref&lt;Database&gt;&gt; openDatabases;
</span><span class="cx">     {
</span><span class="lines">@@ -321,8 +321,11 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-    for (auto&amp; database : openDatabases)
</del><ins>+    for (auto&amp; database : openDatabases) {
+        if (currentQueryBehavior == CurrentQueryBehavior::Interrupt)
+            database-&gt;interrupt();
</ins><span class="cx">         database-&gt;close();
</span><ins>+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String DatabaseTracker::originPath(SecurityOrigin* origin) const
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabaseTrackerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -46,6 +46,8 @@
</span><span class="cx"> class OriginLock;
</span><span class="cx"> class SecurityOrigin;
</span><span class="cx"> 
</span><ins>+enum class CurrentQueryBehavior { Interrupt, RunToCompletion };
+
</ins><span class="cx"> class DatabaseTracker {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(DatabaseTracker); WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="lines">@@ -74,7 +76,7 @@
</span><span class="cx"> 
</span><span class="cx">     unsigned long long getMaxSizeForDatabase(const Database*);
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT void closeAllDatabases();
</del><ins>+    WEBCORE_EXPORT void closeAllDatabases(CurrentQueryBehavior = CurrentQueryBehavior::RunToCompletion);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     explicit DatabaseTracker(const String&amp; databasePath);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformsqlSQLiteDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -334,6 +334,13 @@
</span><span class="cx">     return lastError();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SQLiteDatabase::interrupt()
+{
+    LockHolder locker(m_databaseClosingMutex);
+    if (m_db)
+        sqlite3_interrupt(m_db);
+}
+
</ins><span class="cx"> int64_t SQLiteDatabase::lastInsertRowID()
</span><span class="cx"> {
</span><span class="cx">     if (!m_db)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformsqlSQLiteDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/sql/SQLiteDatabase.h (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/sql/SQLiteDatabase.h        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebCore/platform/sql/SQLiteDatabase.h        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -68,7 +68,10 @@
</span><span class="cx">     int runIncrementalVacuumCommand();
</span><span class="cx">     
</span><span class="cx">     bool transactionInProgress() const { return m_transactionInProgress; }
</span><del>-    
</del><ins>+
+    // Aborts the current database operation. This is thread safe.
+    void interrupt();
+
</ins><span class="cx">     int64_t lastInsertRowID();
</span><span class="cx">     int lastChanges();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebKit/mac/ChangeLog        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2016-05-02  Daniel Bates  &lt;dabates@apple.com&gt;
+
+        DatabaseTracker::closeAllDatabases calls Database::close from the wrong thread
+        https://bugs.webkit.org/show_bug.cgi?id=147672
+        &lt;rdar://problem/22357464&gt;
+
+        Reviewed by Brady Eidson.
+
+        Update the background assertion expiration callback to call DatabaseTracker::closeAllDatabases()
+        with CurrentQueryBehavior::Interrupt so that we abort a long running query and close the database
+        immediately to avoid holding a locked file when the process is suspended.
+
+        * Storage/WebDatabaseManager.mm:
+        (+[WebDatabaseManager startBackgroundTask]):
+
</ins><span class="cx"> 2016-04-29  Dean Jackson  &lt;dino@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         RTL &lt;select&gt; popup menu is in the wrong location
</span></span></pre></div>
<a id="trunkSourceWebKitmacStorageWebDatabaseManagermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -269,7 +269,7 @@
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     setTransactionBackgroundTaskIdentifier(startBackgroundTask(^ {
</span><del>-        DatabaseTracker::tracker().closeAllDatabases();
</del><ins>+        DatabaseTracker::tracker().closeAllDatabases(CurrentQueryBehavior::Interrupt);
</ins><span class="cx">         [WebDatabaseManager endBackgroundTask];
</span><span class="cx">     }));
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebKit2/ChangeLog        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2016-05-02  Daniel Bates  &lt;dabates@apple.com&gt;
+
+        DatabaseTracker::closeAllDatabases calls Database::close from the wrong thread
+        https://bugs.webkit.org/show_bug.cgi?id=147672
+        &lt;rdar://problem/22357464&gt;
+
+        Reviewed by Brady Eidson.
+
+        Call DatabaseTracker::closeAllDatabases() with CurrentQueryBehavior::Interrupt so that we abort
+        a long running query and close the database immediately to avoid holding a locked file when the
+        process is suspended.
+
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::processWillSuspendImminently):
+
</ins><span class="cx"> 2016-05-01  Darin Adler  &lt;darin@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Update Fetch to use enum class instead of string for enumerations
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (200321 => 200322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2016-05-02 12:01:31 UTC (rev 200321)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2016-05-02 15:57:05 UTC (rev 200322)
</span><span class="lines">@@ -1249,7 +1249,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     WEBPROCESS_LOG_ALWAYS(&quot;%p - WebProcess::processWillSuspendImminently()&quot;, this);
</span><del>-    DatabaseTracker::tracker().closeAllDatabases();
</del><ins>+    DatabaseTracker::tracker().closeAllDatabases(CurrentQueryBehavior::Interrupt);
</ins><span class="cx">     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
</span><span class="cx">     handled = true;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>