<!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>[195537] 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/195537">195537</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-01-25 09:13:40 -0800 (Mon, 25 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION(<a href="http://trac.webkit.org/projects/webkit/changeset/192773">r192773</a>): [GTK] maps.google.com unresponsive/stalls since <a href="http://trac.webkit.org/projects/webkit/changeset/192773">r192773</a>
https://bugs.webkit.org/show_bug.cgi?id=153194

Reviewed by Michael Catanzaro.

In <a href="http://trac.webkit.org/projects/webkit/changeset/192773">r192773</a> we implemented the JavaScriptCore garbage collector
timers for the GTK+ port. Those timers schedule sources in the
current thread default main context, but JS web worker threads
implementation doesn't use WTF::RunLoop, but its own WorkerRunLoop
class that doesn't create a GMainContext for the new thread. This
means that for web sites using workers, we are now doing garbage
collection of worker VMs in the main thread which ends up in a
deadlock at some point. We need to ensure that worker threads
create a GMainContext and push it as the default one for the
thread before the WorkerGlobalScope is created. This way when the
worker Heap is created, the GC timers use the right context to
schedule their sources. And then we need to check if there are
sources pending in the thread main context on every worker run
loop iteration.

* workers/WorkerRunLoop.cpp:
(WebCore::WorkerRunLoop::runInMode):
* workers/WorkerThread.cpp:
(WebCore::WorkerThread::workerThread):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreworkersWorkerRunLoopcpp">trunk/Source/WebCore/workers/WorkerRunLoop.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersWorkerThreadcpp">trunk/Source/WebCore/workers/WorkerThread.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (195536 => 195537)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-25 16:19:30 UTC (rev 195536)
+++ trunk/Source/WebCore/ChangeLog        2016-01-25 17:13:40 UTC (rev 195537)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2016-01-25  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        REGRESSION(r192773): [GTK] maps.google.com unresponsive/stalls since r192773
+        https://bugs.webkit.org/show_bug.cgi?id=153194
+
+        Reviewed by Michael Catanzaro.
+
+        In r192773 we implemented the JavaScriptCore garbage collector
+        timers for the GTK+ port. Those timers schedule sources in the
+        current thread default main context, but JS web worker threads
+        implementation doesn't use WTF::RunLoop, but its own WorkerRunLoop
+        class that doesn't create a GMainContext for the new thread. This
+        means that for web sites using workers, we are now doing garbage
+        collection of worker VMs in the main thread which ends up in a
+        deadlock at some point. We need to ensure that worker threads
+        create a GMainContext and push it as the default one for the
+        thread before the WorkerGlobalScope is created. This way when the
+        worker Heap is created, the GC timers use the right context to
+        schedule their sources. And then we need to check if there are
+        sources pending in the thread main context on every worker run
+        loop iteration.
+
+        * workers/WorkerRunLoop.cpp:
+        (WebCore::WorkerRunLoop::runInMode):
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThread::workerThread):
+
</ins><span class="cx"> 2016-01-25  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r195533.
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersWorkerRunLoopcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/WorkerRunLoop.cpp (195536 => 195537)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/WorkerRunLoop.cpp        2016-01-25 16:19:30 UTC (rev 195536)
+++ trunk/Source/WebCore/workers/WorkerRunLoop.cpp        2016-01-25 17:13:40 UTC (rev 195537)
</span><span class="lines">@@ -39,6 +39,10 @@
</span><span class="cx"> #include &quot;WorkerThread.h&quot;
</span><span class="cx"> #include &lt;wtf/CurrentTime.h&gt;
</span><span class="cx"> 
</span><ins>+#if PLATFORM(GTK)
+#include &lt;glib.h&gt;
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class WorkerSharedTimer final : public SharedTimer {
</span><span class="lines">@@ -142,6 +146,12 @@
</span><span class="cx">     ASSERT(context);
</span><span class="cx">     ASSERT(context-&gt;thread().threadID() == currentThread());
</span><span class="cx"> 
</span><ins>+#if PLATFORM(GTK)
+    GMainContext* mainContext = g_main_context_get_thread_default();
+    if (g_main_context_pending(mainContext))
+        g_main_context_iteration(mainContext, FALSE);
+#endif
+
</ins><span class="cx">     double deadline = MessageQueue&lt;Task&gt;::infiniteTime();
</span><span class="cx"> 
</span><span class="cx"> #if USE(CF)
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersWorkerThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/WorkerThread.cpp (195536 => 195537)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/WorkerThread.cpp        2016-01-25 16:19:30 UTC (rev 195536)
+++ trunk/Source/WebCore/workers/WorkerThread.cpp        2016-01-25 17:13:40 UTC (rev 195537)
</span><span class="lines">@@ -44,6 +44,10 @@
</span><span class="cx"> #include &quot;WebCoreThread.h&quot;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if PLATFORM(GTK)
+#include &lt;wtf/glib/GRefPtr.h&gt;
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> static StaticLock threadSetMutex;
</span><span class="lines">@@ -134,6 +138,11 @@
</span><span class="cx">     FloatingPointEnvironment::singleton().propagateMainThreadEnvironment();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if PLATFORM(GTK)
+    GRefPtr&lt;GMainContext&gt; mainContext = adoptGRef(g_main_context_new());
+    g_main_context_push_thread_default(mainContext.get());
+#endif
+
</ins><span class="cx">     {
</span><span class="cx">         LockHolder lock(m_threadCreationMutex);
</span><span class="cx">         m_workerGlobalScope = createWorkerGlobalScope(m_startupData-&gt;m_scriptURL, m_startupData-&gt;m_userAgent, m_startupData-&gt;m_contentSecurityPolicy, m_startupData-&gt;m_contentSecurityPolicyType, m_startupData-&gt;m_topOrigin.release());
</span><span class="lines">@@ -154,6 +163,10 @@
</span><span class="cx"> 
</span><span class="cx">     runEventLoop();
</span><span class="cx"> 
</span><ins>+#if PLATFORM(GTK)
+    g_main_context_pop_thread_default(mainContext.get());
+#endif
+
</ins><span class="cx">     ThreadIdentifier threadID = m_threadID;
</span><span class="cx"> 
</span><span class="cx">     ASSERT(m_workerGlobalScope-&gt;hasOneRef());
</span></span></pre>
</div>
</div>

</body>
</html>