<!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>[201302] 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/201302">201302</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2016-05-23 16:14:33 -0700 (Mon, 23 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Speculative fix for:
Modern IDB: Some blob tests ASSERT sometimes on the bots.
https://bugs.webkit.org/show_bug.cgi?id=157525

Reviewed by Alex Christensen.

No new tests (Should fix existing flakiness, not reproducibly testable).

For all of the lambdas involved in this operation, explicitly WTFMove all of the arguments around.

Critically, this includes the RefPtr&lt;TransactionOperation&gt; protector as well as the
std::function&lt;void ()&gt; completionHandler(s).

By doing so, this removes the possibility of a race between the background thread and the main thread
tearing down the TransactionOperation, guaranteeing that it is torn down on its original thread.

* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::putOrAddOnServer):
* bindings/js/SerializedScriptValue.cpp:
(WebCore::SerializedScriptValue::writeBlobsToDiskForIndexedDB):
* platform/network/BlobRegistryImpl.cpp:
(WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBTransactioncpp">trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsSerializedScriptValuecpp">trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkBlobRegistryImplcpp">trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (201301 => 201302)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-05-23 22:46:41 UTC (rev 201301)
+++ trunk/Source/WebCore/ChangeLog        2016-05-23 23:14:33 UTC (rev 201302)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2016-05-23  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Speculative fix for:
+        Modern IDB: Some blob tests ASSERT sometimes on the bots.
+        https://bugs.webkit.org/show_bug.cgi?id=157525
+
+        Reviewed by Alex Christensen.
+
+        No new tests (Should fix existing flakiness, not reproducibly testable).
+
+        For all of the lambdas involved in this operation, explicitly WTFMove all of the arguments around.
+        
+        Critically, this includes the RefPtr&lt;TransactionOperation&gt; protector as well as the 
+        std::function&lt;void ()&gt; completionHandler(s).
+        
+        By doing so, this removes the possibility of a race between the background thread and the main thread
+        tearing down the TransactionOperation, guaranteeing that it is torn down on its original thread.
+        
+        * Modules/indexeddb/IDBTransaction.cpp:
+        (WebCore::IDBTransaction::putOrAddOnServer):
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::SerializedScriptValue::writeBlobsToDiskForIndexedDB):
+        * platform/network/BlobRegistryImpl.cpp:
+        (WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):
+
</ins><span class="cx"> 2016-05-23  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r201296.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBTransactioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (201301 => 201302)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp        2016-05-23 22:46:41 UTC (rev 201301)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp        2016-05-23 23:14:33 UTC (rev 201302)
</span><span class="lines">@@ -959,7 +959,7 @@
</span><span class="cx">             // In that case, we cannot successfully store this record, so we callback with an error.
</span><span class="cx">             RefPtr&lt;IDBClient::TransactionOperation&gt; protectedOperation(&amp;operation);
</span><span class="cx">             auto result = IDBResultData::error(operation.identifier(), { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Error preparing Blob/File data to be stored in object store&quot;) });
</span><del>-            scriptExecutionContext()-&gt;postTask([protectedOperation, result](ScriptExecutionContext&amp;) {
</del><ins>+            scriptExecutionContext()-&gt;postTask([protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)](ScriptExecutionContext&amp;) {
</ins><span class="cx">                 protectedOperation-&gt;completed(result);
</span><span class="cx">             });
</span><span class="cx">         }
</span><span class="lines">@@ -968,7 +968,7 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;IDBTransaction&gt; protectedThis(this);
</span><span class="cx">     RefPtr&lt;IDBClient::TransactionOperation&gt; protectedOperation(&amp;operation);
</span><del>-    value-&gt;writeBlobsToDiskForIndexedDB([protectedThis, this, protectedOperation, key, value, overwriteMode](const IDBValue&amp; idbValue) {
</del><ins>+    value-&gt;writeBlobsToDiskForIndexedDB([protectedThis = WTFMove(protectedThis), this, protectedOperation = WTFMove(protectedOperation), key = WTFMove(key), value = WTFMove(value), overwriteMode](const IDBValue&amp; idbValue) mutable {
</ins><span class="cx">         ASSERT(currentThread() == originThreadID());
</span><span class="cx">         ASSERT(isMainThread());
</span><span class="cx">         if (idbValue.data().data()) {
</span><span class="lines">@@ -979,7 +979,7 @@
</span><span class="cx">         // If the IDBValue doesn't have any data, then something went wrong writing the blobs to disk.
</span><span class="cx">         // In that case, we cannot successfully store this record, so we callback with an error.
</span><span class="cx">         auto result = IDBResultData::error(protectedOperation-&gt;identifier(), { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Error preparing Blob/File data to be stored in object store&quot;) });
</span><del>-        callOnMainThread([protectedThis, this, protectedOperation, result]() {
</del><ins>+        callOnMainThread([protectedThis = WTFMove(protectedThis), this, protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)]() {
</ins><span class="cx">             protectedOperation-&gt;completed(result);
</span><span class="cx">         });
</span><span class="cx">     });
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsSerializedScriptValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (201301 => 201302)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp        2016-05-23 22:46:41 UTC (rev 201301)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp        2016-05-23 23:14:33 UTC (rev 201302)
</span><span class="lines">@@ -2802,7 +2802,7 @@
</span><span class="cx">     ASSERT(hasBlobURLs());
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;SerializedScriptValue&gt; protectedThis(this);
</span><del>-    blobRegistry().writeBlobsToTemporaryFiles(m_blobURLs, [completionHandler, this, protectedThis](const Vector&lt;String&gt;&amp; blobFilePaths) {
</del><ins>+    blobRegistry().writeBlobsToTemporaryFiles(m_blobURLs, [completionHandler = WTFMove(completionHandler), this, protectedThis = WTFMove(protectedThis)](const Vector&lt;String&gt;&amp; blobFilePaths) {
</ins><span class="cx">         ASSERT(isMainThread());
</span><span class="cx"> 
</span><span class="cx">         if (blobFilePaths.isEmpty()) {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkBlobRegistryImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp (201301 => 201302)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp        2016-05-23 22:46:41 UTC (rev 201301)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp        2016-05-23 23:14:33 UTC (rev 201302)
</span><span class="lines">@@ -284,11 +284,11 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    blobUtilityQueue().dispatch([blobsForWriting, completionHandler]() {
</del><ins>+    blobUtilityQueue().dispatch([blobsForWriting = WTFMove(blobsForWriting), completionHandler = WTFMove(completionHandler)]() mutable {
</ins><span class="cx">         Vector&lt;String&gt; filePaths;
</span><span class="cx"> 
</span><del>-        ScopeGuard completionCaller([completionHandler]() {
-            callOnMainThread([completionHandler]() {
</del><ins>+        ScopeGuard completionCaller([completionHandler]() mutable {
+            callOnMainThread([completionHandler = WTFMove(completionHandler)]() {
</ins><span class="cx">                 Vector&lt;String&gt; filePaths;
</span><span class="cx">                 completionHandler(filePaths);
</span><span class="cx">             });
</span><span class="lines">@@ -328,7 +328,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         completionCaller.disable();
</span><del>-        callOnMainThread([completionHandler, filePaths]() {
</del><ins>+        callOnMainThread([completionHandler = WTFMove(completionHandler), filePaths = WTFMove(filePaths)]() {
</ins><span class="cx">             completionHandler(filePaths);
</span><span class="cx">         });
</span><span class="cx">     });
</span></span></pre>
</div>
</div>

</body>
</html>