<!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>[174638] releases/WebKitGTK/webkit-2.6</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/174638">174638</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2014-10-12 02:18:47 -0700 (Sun, 12 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/174632">r174632</a> - [GLIB] Split GMainLoopSource moving thread safe implementation to its own class GThreadSafeMainLoopSource
https://bugs.webkit.org/show_bug.cgi?id=137485

Reviewed by Sergio Villar Senin.

Source/WebCore:

Use GThreadSafeMainLoopSource for GStreamer sources, since they
can be used from different threads. Also update GMutexLocker
usages, since it's now a template.

* platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
(WebCore::AudioFileReader::createBus):
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::MediaPlayerPrivateGStreamerBase::updateTexture):
(WebCore::MediaPlayerPrivateGStreamerBase::triggerRepaint):
(WebCore::MediaPlayerPrivateGStreamerBase::paint):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
* platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
(webkitVideoSinkTimeoutCallback):
(webkitVideoSinkRender):
(unlockBufferMutex):
(webkitVideoSinkUnlockStop):
(webkitVideoSinkStart):
* platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp:
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
(webKitWebSrcGetProperty):
(webKitWebSrcStop):
(webKitWebSrcStart):
(webKitWebSrcChangeState):
(webKitWebSrcQueryWithParent):
(webKitWebSrcGetUri):
(webKitWebSrcSetUri):
(webKitWebSrcNeedDataMainCb):
(webKitWebSrcNeedDataCb):
(webKitWebSrcEnoughDataMainCb):
(webKitWebSrcEnoughDataCb):
(webKitWebSrcSeekDataCb):
(webKitWebSrcSetMediaPlayer):
(StreamingClient::createReadBuffer):
(StreamingClient::handleResponseReceived):
(StreamingClient::handleDataReceived):
(StreamingClient::handleNotifyFinished):
(ResourceHandleStreamingClient::wasBlocked):
(ResourceHandleStreamingClient::cannotShowURL):

Source/WTF:

We made GMainLoopSource thread safe, but in most of the cases we
know the sources are used by a single thread, which has an impact
in the performance (mutex, GCancellable, etc.). The new class
GThreadSafeMainLoopSource inherits from GMainLoopSource overriding
the new virtual methods and calling the parent for the common code.
GMutexLocker now supports recursive mutexes, it's a template that
can wrap a GMutex or a GRecMutex. GThreadSafeMainLoopSource uses a
recursive mutex using the new GMutexLocker API.

* wtf/PlatformEfl.cmake: Add new file to compilation.
* wtf/PlatformGTK.cmake: Ditto.
* wtf/gobject/GMainLoopSource.cpp:
(WTF::GMainLoopSource::GMainLoopSource):
(WTF::GMainLoopSource::~GMainLoopSource):
(WTF::GMainLoopSource::cancel):
(WTF::GMainLoopSource::schedule):
(WTF::GMainLoopSource::scheduleAfterDelay):
(WTF::GMainLoopSource::prepareVoidCallback):
(WTF::GMainLoopSource::finishVoidCallback):
(WTF::GMainLoopSource::voidCallback):
(WTF::GMainLoopSource::prepareBoolCallback):
(WTF::GMainLoopSource::finishBoolCallback):
(WTF::GMainLoopSource::boolCallback):
(WTF::GMainLoopSource::socketCallback):
(WTF::GMainLoopSource::cancelWithoutLocking): Deleted.
* wtf/gobject/GMainLoopSource.h:
* wtf/gobject/GMutexLocker.h:
(WTF::MutexWrapper&lt;GMutex&gt;::lock):
(WTF::MutexWrapper&lt;GMutex&gt;::unlock):
(WTF::MutexWrapper&lt;GRecMutex&gt;::lock):
(WTF::MutexWrapper&lt;GRecMutex&gt;::unlock):
(WTF::GMutexLocker::GMutexLocker):
(WTF::GMutexLocker::lock):
(WTF::GMutexLocker::unlock):
* wtf/gobject/GThreadSafeMainLoopSource.cpp: Added.
(WTF::GThreadSafeMainLoopSource::GThreadSafeMainLoopSource):
(WTF::GThreadSafeMainLoopSource::~GThreadSafeMainLoopSource):
(WTF::GThreadSafeMainLoopSource::cancel):
(WTF::GThreadSafeMainLoopSource::schedule):
(WTF::GThreadSafeMainLoopSource::scheduleAfterDelay):
(WTF::GThreadSafeMainLoopSource::prepareVoidCallback):
(WTF::GThreadSafeMainLoopSource::finishVoidCallback):
(WTF::GThreadSafeMainLoopSource::voidCallback):
(WTF::GThreadSafeMainLoopSource::prepareBoolCallback):
(WTF::GThreadSafeMainLoopSource::finishBoolCallback):
(WTF::GThreadSafeMainLoopSource::boolCallback):
* wtf/gobject/GThreadSafeMainLoopSource.h: Added.

Tools:

Update GMainLoopSource tests. Most of the tests are now run twice,
first with a GMainLoopSource and then with a
GThreadSafeMainLoopSource, since both should have the same
behaviour. The threading test uses GThreadSafeMainLoopSource and
the delete on destroy test uses GMainLoopSource. The tests
themselves haven't changed, since there's no change in behaviour.

* TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp:
(TestWebKitAPI::GMainLoopSourceTest::source):
(TestWebKitAPI::basicRescheduling):
(TestWebKitAPI::TEST):
(TestWebKitAPI::reentrantRescheduling):
(TestWebKitAPI::cancelRepeatingSourceDuringDispatch):
(TestWebKitAPI::basicDestroyCallbacks):
(TestWebKitAPI::destroyCallbacksAfterCancellingDuringDispatch):
(TestWebKitAPI::destroyCallbacksAfterReschedulingDuringDispatch):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit26SourceWTFChangeLog">releases/WebKitGTK/webkit-2.6/Source/WTF/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWTFwtfPlatformEflcmake">releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformEfl.cmake</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWTFwtfPlatformGTKcmake">releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformGTK.cmake</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWTFwtfgobjectGMainLoopSourcecpp">releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWTFwtfgobjectGMainLoopSourceh">releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.h</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWTFwtfgobjectGMutexLockerh">releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMutexLocker.h</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreplatformaudiogstreamerAudioFileReaderGStreamercpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerInbandTextTrackPrivateGStreamerh">releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerh">releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerBasecpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerBaseh">releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerTrackPrivateBaseGStreamerh">releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerVideoSinkGStreamercpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerWebKitMediaSourceGStreamercpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerWebKitWebSourceGStreamercpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26ToolsChangeLog">releases/WebKitGTK/webkit-2.6/Tools/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit26ToolsTestWebKitAPITestsWTFgobjectGMainLoopSourcecpp">releases/WebKitGTK/webkit-2.6/Tools/TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit26SourceWTFwtfgobjectGThreadSafeMainLoopSourcecpp">releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWTFwtfgobjectGThreadSafeMainLoopSourceh">releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit26SourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/ChangeLog (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WTF/ChangeLog        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/ChangeLog        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -1,3 +1,58 @@
</span><ins>+2014-10-11  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GLIB] Split GMainLoopSource moving thread safe implementation to its own class GThreadSafeMainLoopSource
+        https://bugs.webkit.org/show_bug.cgi?id=137485
+
+        Reviewed by Sergio Villar Senin.
+
+        We made GMainLoopSource thread safe, but in most of the cases we
+        know the sources are used by a single thread, which has an impact
+        in the performance (mutex, GCancellable, etc.). The new class
+        GThreadSafeMainLoopSource inherits from GMainLoopSource overriding
+        the new virtual methods and calling the parent for the common code.
+        GMutexLocker now supports recursive mutexes, it's a template that
+        can wrap a GMutex or a GRecMutex. GThreadSafeMainLoopSource uses a
+        recursive mutex using the new GMutexLocker API.
+
+        * wtf/PlatformEfl.cmake: Add new file to compilation.
+        * wtf/PlatformGTK.cmake: Ditto.
+        * wtf/gobject/GMainLoopSource.cpp:
+        (WTF::GMainLoopSource::GMainLoopSource):
+        (WTF::GMainLoopSource::~GMainLoopSource):
+        (WTF::GMainLoopSource::cancel):
+        (WTF::GMainLoopSource::schedule):
+        (WTF::GMainLoopSource::scheduleAfterDelay):
+        (WTF::GMainLoopSource::prepareVoidCallback):
+        (WTF::GMainLoopSource::finishVoidCallback):
+        (WTF::GMainLoopSource::voidCallback):
+        (WTF::GMainLoopSource::prepareBoolCallback):
+        (WTF::GMainLoopSource::finishBoolCallback):
+        (WTF::GMainLoopSource::boolCallback):
+        (WTF::GMainLoopSource::socketCallback):
+        (WTF::GMainLoopSource::cancelWithoutLocking): Deleted.
+        * wtf/gobject/GMainLoopSource.h:
+        * wtf/gobject/GMutexLocker.h:
+        (WTF::MutexWrapper&lt;GMutex&gt;::lock):
+        (WTF::MutexWrapper&lt;GMutex&gt;::unlock):
+        (WTF::MutexWrapper&lt;GRecMutex&gt;::lock):
+        (WTF::MutexWrapper&lt;GRecMutex&gt;::unlock):
+        (WTF::GMutexLocker::GMutexLocker):
+        (WTF::GMutexLocker::lock):
+        (WTF::GMutexLocker::unlock):
+        * wtf/gobject/GThreadSafeMainLoopSource.cpp: Added.
+        (WTF::GThreadSafeMainLoopSource::GThreadSafeMainLoopSource):
+        (WTF::GThreadSafeMainLoopSource::~GThreadSafeMainLoopSource):
+        (WTF::GThreadSafeMainLoopSource::cancel):
+        (WTF::GThreadSafeMainLoopSource::schedule):
+        (WTF::GThreadSafeMainLoopSource::scheduleAfterDelay):
+        (WTF::GThreadSafeMainLoopSource::prepareVoidCallback):
+        (WTF::GThreadSafeMainLoopSource::finishVoidCallback):
+        (WTF::GThreadSafeMainLoopSource::voidCallback):
+        (WTF::GThreadSafeMainLoopSource::prepareBoolCallback):
+        (WTF::GThreadSafeMainLoopSource::finishBoolCallback):
+        (WTF::GThreadSafeMainLoopSource::boolCallback):
+        * wtf/gobject/GThreadSafeMainLoopSource.h: Added.
+
</ins><span class="cx"> 2014-09-18  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Dot not allow to create delete-on-destroy GMainLoopSources
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWTFwtfPlatformEflcmake"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformEfl.cmake (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformEfl.cmake        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformEfl.cmake        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -4,6 +4,7 @@
</span><span class="cx"> 
</span><span class="cx">     gobject/GMainLoopSource.cpp
</span><span class="cx">     gobject/GRefPtr.cpp
</span><ins>+    gobject/GThreadSafeMainLoopSource.cpp
</ins><span class="cx"> )
</span><span class="cx"> 
</span><span class="cx"> list(APPEND WTF_LIBRARIES
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWTFwtfPlatformGTKcmake"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformGTK.cmake (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformGTK.cmake        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformGTK.cmake        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -1,6 +1,7 @@
</span><span class="cx"> list(APPEND WTF_SOURCES
</span><span class="cx">     gobject/GMainLoopSource.cpp
</span><span class="cx">     gobject/GRefPtr.cpp
</span><ins>+    gobject/GThreadSafeMainLoopSource.cpp
</ins><span class="cx">     gobject/GlibUtilities.cpp
</span><span class="cx"> 
</span><span class="cx">     gtk/MainThreadGtk.cpp
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWTFwtfgobjectGMainLoopSourcecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.cpp (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.cpp        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.cpp        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -24,12 +24,11 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><ins>+#include &quot;GMainLoopSource.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> #if USE(GLIB)
</span><span class="cx"> 
</span><del>-#include &quot;GMainLoopSource.h&quot;
</del><span class="cx"> #include &lt;gio/gio.h&gt;
</span><del>-#include &lt;wtf/gobject/GMutexLocker.h&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="lines">@@ -42,20 +41,17 @@
</span><span class="cx">     : m_deleteOnDestroy(DoNotDeleteOnDestroy)
</span><span class="cx">     , m_status(Ready)
</span><span class="cx"> {
</span><del>-    g_mutex_init(&amp;m_mutex);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> GMainLoopSource::GMainLoopSource(DeleteOnDestroyType deleteOnDestroy)
</span><span class="cx">     : m_deleteOnDestroy(deleteOnDestroy)
</span><span class="cx">     , m_status(Ready)
</span><span class="cx"> {
</span><del>-    g_mutex_init(&amp;m_mutex);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> GMainLoopSource::~GMainLoopSource()
</span><span class="cx"> {
</span><span class="cx">     cancel();
</span><del>-    g_mutex_clear(&amp;m_mutex);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool GMainLoopSource::isScheduled() const
</span><span class="lines">@@ -70,28 +66,15 @@
</span><span class="cx"> 
</span><span class="cx"> void GMainLoopSource::cancel()
</span><span class="cx"> {
</span><del>-    GMutexLocker locker(m_mutex);
-    cancelWithoutLocking();
-}
-
-void GMainLoopSource::cancelWithoutLocking()
-{
</del><span class="cx">     // Delete-on-destroy GMainLoopSource objects can't be cancelled.
</span><span class="cx">     if (m_deleteOnDestroy == DeleteOnDestroy)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // A valid context should only be present if GMainLoopSource is in the Scheduled or Dispatching state.
</span><span class="cx">     ASSERT(!m_context.source || m_status == Scheduled || m_status == Dispatching);
</span><del>-    // The general cancellable object should only be present if we're currently dispatching this GMainLoopSource.
-    ASSERT(!m_cancellable || m_status == Dispatching);
</del><span class="cx"> 
</span><span class="cx">     m_status = Ready;
</span><span class="cx"> 
</span><del>-    // The source is perhaps being cancelled in the middle of a callback dispatch.
-    // Cancelling this GCancellable object will convey this information to the
-    // current execution context when the callback dispatch is finished.
-    g_cancellable_cancel(m_cancellable.get());
-    m_cancellable = nullptr;
</del><span class="cx">     g_cancellable_cancel(m_context.socketCancellable.get());
</span><span class="cx"> 
</span><span class="cx">     if (!m_context.source)
</span><span class="lines">@@ -115,13 +98,12 @@
</span><span class="cx"> 
</span><span class="cx"> void GMainLoopSource::schedule(const char* name, std::function&lt;void ()&gt; function, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
</span><span class="cx"> {
</span><del>-    GMutexLocker locker(m_mutex);
-    cancelWithoutLocking();
</del><ins>+    cancel();
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(!m_context.source);
</span><span class="cx">     m_context = {
</span><span class="cx">         adoptGRef(g_idle_source_new()),
</span><del>-        adoptGRef(g_cancellable_new()),
</del><ins>+        nullptr, // cancellable
</ins><span class="cx">         nullptr, // socketCancellable
</span><span class="cx">         WTF::move(function),
</span><span class="cx">         nullptr, // boolCallback
</span><span class="lines">@@ -133,13 +115,12 @@
</span><span class="cx"> 
</span><span class="cx"> void GMainLoopSource::schedule(const char* name, std::function&lt;bool ()&gt; function, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
</span><span class="cx"> {
</span><del>-    GMutexLocker locker(m_mutex);
-    cancelWithoutLocking();
</del><ins>+    cancel();
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(!m_context.source);
</span><span class="cx">     m_context = {
</span><span class="cx">         adoptGRef(g_idle_source_new()),
</span><del>-        adoptGRef(g_cancellable_new()),
</del><ins>+        nullptr, // cancellable
</ins><span class="cx">         nullptr, // socketCancellable
</span><span class="cx">         nullptr, // voidCallback
</span><span class="cx">         WTF::move(function),
</span><span class="lines">@@ -151,14 +132,13 @@
</span><span class="cx"> 
</span><span class="cx"> void GMainLoopSource::schedule(const char* name, std::function&lt;bool (GIOCondition)&gt; function, GSocket* socket, GIOCondition condition, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
</span><span class="cx"> {
</span><del>-    GMutexLocker locker(m_mutex);
-    cancelWithoutLocking();
</del><ins>+    cancel();
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(!m_context.source);
</span><span class="cx">     GCancellable* socketCancellable = g_cancellable_new();
</span><span class="cx">     m_context = {
</span><span class="cx">         adoptGRef(g_socket_create_source(socket, condition, socketCancellable)),
</span><del>-        adoptGRef(g_cancellable_new()),
</del><ins>+        nullptr, // cancellable
</ins><span class="cx">         adoptGRef(socketCancellable),
</span><span class="cx">         nullptr, // voidCallback
</span><span class="cx">         nullptr, // boolCallback
</span><span class="lines">@@ -187,13 +167,12 @@
</span><span class="cx"> 
</span><span class="cx"> void GMainLoopSource::scheduleAfterDelay(const char* name, std::function&lt;void ()&gt; function, std::chrono::milliseconds delay, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
</span><span class="cx"> {
</span><del>-    GMutexLocker locker(m_mutex);
-    cancelWithoutLocking();
</del><ins>+    cancel();
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(!m_context.source);
</span><span class="cx">     m_context = {
</span><span class="cx">         adoptGRef(g_timeout_source_new(delay.count())),
</span><del>-        adoptGRef(g_cancellable_new()),
</del><ins>+        nullptr, // cancellable
</ins><span class="cx">         nullptr, // socketCancellable
</span><span class="cx">         WTF::move(function),
</span><span class="cx">         nullptr, // boolCallback
</span><span class="lines">@@ -205,13 +184,12 @@
</span><span class="cx"> 
</span><span class="cx"> void GMainLoopSource::scheduleAfterDelay(const char* name, std::function&lt;bool ()&gt; function, std::chrono::milliseconds delay, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
</span><span class="cx"> {
</span><del>-    GMutexLocker locker(m_mutex);
-    cancelWithoutLocking();
</del><ins>+    cancel();
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(!m_context.source);
</span><span class="cx">     m_context = {
</span><span class="cx">         adoptGRef(g_timeout_source_new(delay.count())),
</span><del>-        adoptGRef(g_cancellable_new()),
</del><ins>+        nullptr, // cancellable
</ins><span class="cx">         nullptr, // socketCancellable
</span><span class="cx">         nullptr, // voidCallback
</span><span class="cx">         WTF::move(function),
</span><span class="lines">@@ -223,13 +201,12 @@
</span><span class="cx"> 
</span><span class="cx"> void GMainLoopSource::scheduleAfterDelay(const char* name, std::function&lt;void ()&gt; function, std::chrono::seconds delay, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
</span><span class="cx"> {
</span><del>-    GMutexLocker locker(m_mutex);
-    cancelWithoutLocking();
</del><ins>+    cancel();
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(!m_context.source);
</span><span class="cx">     m_context = {
</span><span class="cx">         adoptGRef(g_timeout_source_new_seconds(delay.count())),
</span><del>-        adoptGRef(g_cancellable_new()),
</del><ins>+        nullptr, // cancellable
</ins><span class="cx">         nullptr, // socketCancellable
</span><span class="cx">         WTF::move(function),
</span><span class="cx">         nullptr, // boolCallback
</span><span class="lines">@@ -241,13 +218,12 @@
</span><span class="cx"> 
</span><span class="cx"> void GMainLoopSource::scheduleAfterDelay(const char* name, std::function&lt;bool ()&gt; function, std::chrono::seconds delay, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
</span><span class="cx"> {
</span><del>-    GMutexLocker locker(m_mutex);
-    cancelWithoutLocking();
</del><ins>+    cancel();
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(!m_context.source);
</span><span class="cx">     m_context = {
</span><span class="cx">         adoptGRef(g_timeout_source_new_seconds(delay.count())),
</span><del>-        adoptGRef(g_cancellable_new()),
</del><ins>+        nullptr, // cancellable
</ins><span class="cx">         nullptr, // socketCancellable
</span><span class="cx">         nullptr, // voidCallback
</span><span class="cx">         WTF::move(function),
</span><span class="lines">@@ -287,86 +263,80 @@
</span><span class="cx">     create().scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void GMainLoopSource::voidCallback()
</del><ins>+bool GMainLoopSource::prepareVoidCallback(Context&amp; context)
</ins><span class="cx"> {
</span><del>-    Context context;
</del><ins>+    if (!m_context.source)
+        return false;
</ins><span class="cx"> 
</span><del>-    {
-        GMutexLocker locker(m_mutex);
-        if (!m_context.source)
-            return;
</del><ins>+    context = WTF::move(m_context);
</ins><span class="cx"> 
</span><del>-        context = WTF::move(m_context);
</del><ins>+    ASSERT(context.voidCallback);
+    ASSERT(m_status == Scheduled);
+    m_status = Dispatching;
</ins><span class="cx"> 
</span><del>-        ASSERT(context.voidCallback);
-        ASSERT(m_status == Scheduled);
-        m_status = Dispatching;
</del><ins>+    return true;
+}
</ins><span class="cx"> 
</span><del>-        m_cancellable = context.cancellable;
-    }
</del><ins>+void GMainLoopSource::finishVoidCallback()
+{
+    m_status = Ready;
+}
</ins><span class="cx"> 
</span><del>-    context.voidCallback();
-
-    if (g_cancellable_is_cancelled(context.cancellable.get())) {
-        context.destroySource();
</del><ins>+void GMainLoopSource::voidCallback()
+{
+    Context context;
+    if (!prepareVoidCallback(context))
</ins><span class="cx">         return;
</span><del>-    }
</del><span class="cx"> 
</span><del>-    bool shouldSelfDestruct = false;
-    {
-        GMutexLocker locker(m_mutex);
-        m_status = Ready;
-        m_cancellable = nullptr;
-        shouldSelfDestruct = m_deleteOnDestroy == DeleteOnDestroy;
</del><ins>+    context.voidCallback();
+    if (m_status != Ready &amp;&amp; !m_context.source) {
+        // Switch to Ready if it hasn't been re-scheduled or cancelled.
+        finishVoidCallback();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     context.destroySource();
</span><del>-    if (shouldSelfDestruct)
</del><ins>+    if (m_deleteOnDestroy == DeleteOnDestroy)
</ins><span class="cx">         delete this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool GMainLoopSource::boolCallback()
</del><ins>+bool GMainLoopSource::prepareBoolCallback(Context&amp; context)
</ins><span class="cx"> {
</span><del>-    Context context;
</del><ins>+    if (!m_context.source)
+        return false;
</ins><span class="cx"> 
</span><del>-    {
-        GMutexLocker locker(m_mutex);
-        if (!m_context.source)
-            return Stop;
</del><ins>+    context = WTF::move(m_context);
</ins><span class="cx"> 
</span><del>-        context = WTF::move(m_context);
</del><ins>+    ASSERT(context.boolCallback);
+    ASSERT(m_status == Scheduled || m_status == Dispatching);
+    m_status = Dispatching;
+    return true;
+}
</ins><span class="cx"> 
</span><del>-        ASSERT(context.boolCallback);
-        ASSERT(m_status == Scheduled || m_status == Dispatching);
-        m_status = Dispatching;
</del><ins>+void GMainLoopSource::finishBoolCallback(bool retval, Context&amp; context)
+{
+    // m_status should reflect whether the GMainLoopSource has been rescheduled during dispatch.
+    ASSERT((!m_context.source &amp;&amp; m_status == Dispatching) || m_status == Scheduled);
+    if (retval &amp;&amp; !m_context.source)
+        m_context = WTF::move(context);
+    else if (!retval)
+        m_status = Ready;
+}
</ins><span class="cx"> 
</span><del>-        m_cancellable = context.cancellable;
-    }
</del><ins>+bool GMainLoopSource::boolCallback()
+{
+    Context context;
+    if (!prepareBoolCallback(context))
+        return Stop;
</ins><span class="cx"> 
</span><span class="cx">     bool retval = context.boolCallback();
</span><del>-
-    if (g_cancellable_is_cancelled(context.cancellable.get())) {
-        context.destroySource();
-        return Stop;
</del><ins>+    if (m_status != Ready &amp;&amp; !m_context.source) {
+        // Prepare for a new iteration or switch to Ready if it hasn't been re-scheduled or cancelled.
+        finishBoolCallback(retval, context);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool shouldSelfDestruct = false;
-    {
-        GMutexLocker locker(m_mutex);
-        m_cancellable = nullptr;
-        shouldSelfDestruct = m_deleteOnDestroy == DeleteOnDestroy;
-
-        // m_status should reflect whether the GMainLoopSource has been rescheduled during dispatch.
-        ASSERT((!m_context.source &amp;&amp; m_status == Dispatching) || m_status == Scheduled);
-        if (retval &amp;&amp; !m_context.source)
-            m_context = WTF::move(context);
-        else if (!retval)
-            m_status = Ready;
-    }
-
</del><span class="cx">     if (context.source) {
</span><span class="cx">         context.destroySource();
</span><del>-        if (shouldSelfDestruct)
</del><ins>+        if (m_deleteOnDestroy == DeleteOnDestroy)
</ins><span class="cx">             delete this;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -375,22 +345,15 @@
</span><span class="cx"> 
</span><span class="cx"> bool GMainLoopSource::socketCallback(GIOCondition condition)
</span><span class="cx"> {
</span><del>-    Context context;
</del><ins>+    if (!m_context.source)
+        return Stop;
</ins><span class="cx"> 
</span><del>-    {
-        GMutexLocker locker(m_mutex);
-        if (!m_context.source)
-            return Stop;
</del><ins>+    Context context = WTF::move(m_context);
</ins><span class="cx"> 
</span><del>-        context = WTF::move(m_context);
</del><ins>+    ASSERT(context.socketCallback);
+    ASSERT(m_status == Scheduled || m_status == Dispatching);
+    m_status = Dispatching;
</ins><span class="cx"> 
</span><del>-        ASSERT(context.socketCallback);
-        ASSERT(m_status == Scheduled || m_status == Dispatching);
-        m_status = Dispatching;
-
-        m_cancellable = context.cancellable;
-    }
-
</del><span class="cx">     if (g_cancellable_is_cancelled(context.socketCancellable.get())) {
</span><span class="cx">         context.destroySource();
</span><span class="cx">         return Stop;
</span><span class="lines">@@ -398,18 +361,9 @@
</span><span class="cx"> 
</span><span class="cx">     bool retval = context.socketCallback(condition);
</span><span class="cx"> 
</span><del>-    if (g_cancellable_is_cancelled(context.cancellable.get())) {
-        context.destroySource();
-        return Stop;
-    }
-
-    {
-        GMutexLocker locker(m_mutex);
-        m_cancellable = nullptr;
-
</del><ins>+    if (m_status != Ready &amp;&amp; !m_context.source) {
</ins><span class="cx">         // m_status should reflect whether the GMainLoopSource has been rescheduled during dispatch.
</span><span class="cx">         ASSERT((!m_context.source &amp;&amp; m_status == Dispatching) || m_status == Scheduled);
</span><del>-
</del><span class="cx">         if (retval &amp;&amp; !m_context.source)
</span><span class="cx">             m_context = WTF::move(context);
</span><span class="cx">         else if (!retval)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWTFwtfgobjectGMainLoopSourceh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.h (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.h        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.h        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -26,13 +26,14 @@
</span><span class="cx"> #ifndef GMainLoopSource_h
</span><span class="cx"> #define GMainLoopSource_h
</span><span class="cx"> 
</span><ins>+#if USE(GLIB)
+
</ins><span class="cx"> #include &lt;functional&gt;
</span><span class="cx"> #include &lt;glib.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/gobject/GRefPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> typedef struct _GSocket GSocket;
</span><del>-typedef union _GMutex GMutex;
</del><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="lines">@@ -41,7 +42,7 @@
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx">     WTF_EXPORT_PRIVATE GMainLoopSource();
</span><del>-    WTF_EXPORT_PRIVATE ~GMainLoopSource();
</del><ins>+    WTF_EXPORT_PRIVATE virtual ~GMainLoopSource();
</ins><span class="cx"> 
</span><span class="cx">     static const bool Stop = false;
</span><span class="cx">     static const bool Continue = true;
</span><span class="lines">@@ -49,14 +50,15 @@
</span><span class="cx">     WTF_EXPORT_PRIVATE bool isScheduled() const;
</span><span class="cx">     WTF_EXPORT_PRIVATE bool isActive() const;
</span><span class="cx"> 
</span><del>-    WTF_EXPORT_PRIVATE void schedule(const char* name, std::function&lt;void()&gt;, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
-    WTF_EXPORT_PRIVATE void schedule(const char* name, std::function&lt;bool()&gt;, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
</del><ins>+    WTF_EXPORT_PRIVATE virtual void schedule(const char* name, std::function&lt;void()&gt;, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
+    WTF_EXPORT_PRIVATE virtual void schedule(const char* name, std::function&lt;bool()&gt;, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
+    WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function&lt;void()&gt;, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
+    WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function&lt;bool()&gt;, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
+    WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function&lt;void()&gt;, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
+    WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function&lt;bool()&gt;, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
+    WTF_EXPORT_PRIVATE virtual void cancel();
+
</ins><span class="cx">     WTF_EXPORT_PRIVATE void schedule(const char* name, std::function&lt;bool(GIOCondition)&gt;, GSocket*, GIOCondition, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
</span><del>-    WTF_EXPORT_PRIVATE void scheduleAfterDelay(const char* name, std::function&lt;void()&gt;, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
-    WTF_EXPORT_PRIVATE void scheduleAfterDelay(const char* name, std::function&lt;bool()&gt;, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
-    WTF_EXPORT_PRIVATE void scheduleAfterDelay(const char* name, std::function&lt;void()&gt;, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
-    WTF_EXPORT_PRIVATE void scheduleAfterDelay(const char* name, std::function&lt;bool()&gt;, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
-    WTF_EXPORT_PRIVATE void cancel();
</del><span class="cx"> 
</span><span class="cx">     static void scheduleAndDeleteOnDestroy(const char* name, std::function&lt;void()&gt;, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
</span><span class="cx">     static void scheduleAndDeleteOnDestroy(const char* name, std::function&lt;bool()&gt;, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
</span><span class="lines">@@ -65,51 +67,58 @@
</span><span class="cx">     static void scheduleAfterDelayAndDeleteOnDestroy(const char* name, std::function&lt;void()&gt;, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
</span><span class="cx">     static void scheduleAfterDelayAndDeleteOnDestroy(const char* name, std::function&lt;bool()&gt;, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr);
</span><span class="cx"> 
</span><ins>+protected:
+    enum Status { Ready, Scheduled, Dispatching };
+
+    struct Context {
+        Context() = default;
+        Context(Context&amp;&amp;) = default;
+        Context&amp; operator=(Context&amp;&amp;) = default;
+
+        void destroySource();
+
+        GRefPtr&lt;GSource&gt; source;
+        GRefPtr&lt;GCancellable&gt; cancellable;
+        GRefPtr&lt;GCancellable&gt; socketCancellable;
+        std::function&lt;void ()&gt; voidCallback;
+        std::function&lt;bool ()&gt; boolCallback;
+        std::function&lt;bool (GIOCondition)&gt; socketCallback;
+        std::function&lt;void ()&gt; destroyCallback;
+    };
+
+    virtual void voidCallback();
+    virtual bool boolCallback();
+
+    virtual bool prepareVoidCallback(Context&amp;);
+    virtual void finishVoidCallback();
+    virtual bool prepareBoolCallback(Context&amp;);
+    virtual void finishBoolCallback(bool retval, Context&amp;);
+
</ins><span class="cx"> private:
</span><span class="cx">     static GMainLoopSource&amp; create();
</span><span class="cx"> 
</span><span class="cx">     enum DeleteOnDestroyType { DeleteOnDestroy, DoNotDeleteOnDestroy };
</span><span class="cx">     GMainLoopSource(DeleteOnDestroyType);
</span><span class="cx"> 
</span><del>-    enum Status { Ready, Scheduled, Dispatching };
-
-    void cancelWithoutLocking();
</del><span class="cx">     void scheduleIdleSource(const char* name, GSourceFunc, int priority, GMainContext*);
</span><span class="cx">     void scheduleTimeoutSource(const char* name, GSourceFunc, int priority, GMainContext*);
</span><del>-    void voidCallback();
-    bool boolCallback();
</del><span class="cx">     bool socketCallback(GIOCondition);
</span><span class="cx"> 
</span><del>-    void destroy();
-
</del><span class="cx">     static gboolean voidSourceCallback(GMainLoopSource*);
</span><span class="cx">     static gboolean boolSourceCallback(GMainLoopSource*);
</span><span class="cx">     static gboolean socketSourceCallback(GSocket*, GIOCondition, GMainLoopSource*);
</span><span class="cx"> 
</span><span class="cx">     DeleteOnDestroyType m_deleteOnDestroy;
</span><ins>+
+protected:
+    Context m_context;
</ins><span class="cx">     Status m_status;
</span><del>-    GMutex m_mutex;
-    GRefPtr&lt;GCancellable&gt; m_cancellable;
-
-    struct Context {
-        Context() = default;
-        Context(Context&amp;&amp;) = default;
-        Context&amp; operator=(Context&amp;&amp;) = default;
-
-        void destroySource();
-
-        GRefPtr&lt;GSource&gt; source;
-        GRefPtr&lt;GCancellable&gt; cancellable;
-        GRefPtr&lt;GCancellable&gt; socketCancellable;
-        std::function&lt;void ()&gt; voidCallback;
-        std::function&lt;bool ()&gt; boolCallback;
-        std::function&lt;bool (GIOCondition)&gt; socketCallback;
-        std::function&lt;void ()&gt; destroyCallback;
-    } m_context;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> using WTF::GMainLoopSource;
</span><span class="cx"> 
</span><ins>+#endif // USE(GLIB)
+
</ins><span class="cx"> #endif // GMainLoopSource_h
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWTFwtfgobjectGMutexLockerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMutexLocker.h (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMutexLocker.h        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMutexLocker.h        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -27,10 +27,40 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><ins>+template&lt;typename T&gt;
+struct MutexWrapper;
+
+template&lt;&gt;
+struct MutexWrapper&lt;GMutex&gt; {
+    static void lock(GMutex* mutex)
+    {
+        g_mutex_lock(mutex);
+    }
+
+    static void unlock(GMutex* mutex)
+    {
+        g_mutex_unlock(mutex);
+    }
+};
+
+template&lt;&gt;
+struct MutexWrapper&lt;GRecMutex&gt; {
+    static void lock(GRecMutex* mutex)
+    {
+        g_rec_mutex_lock(mutex);
+    }
+
+    static void unlock(GRecMutex* mutex)
+    {
+        g_rec_mutex_unlock(mutex);
+    }
+};
+
+template&lt;typename T&gt;
</ins><span class="cx"> class GMutexLocker {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(GMutexLocker);
</span><span class="cx"> public:
</span><del>-    explicit GMutexLocker(GMutex&amp; mutex)
</del><ins>+    explicit GMutexLocker(T&amp; mutex)
</ins><span class="cx">         : m_mutex(mutex)
</span><span class="cx">         , m_locked(false)
</span><span class="cx">     {
</span><span class="lines">@@ -44,22 +74,24 @@
</span><span class="cx"> 
</span><span class="cx">     void lock()
</span><span class="cx">     {
</span><del>-        if (!m_locked) {
-            g_mutex_lock(&amp;m_mutex);
-            m_locked = true;
-        }
</del><ins>+        if (m_locked)
+            return;
+
+        MutexWrapper&lt;T&gt;::lock(&amp;m_mutex);
+        m_locked = true;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void unlock()
</span><span class="cx">     {
</span><del>-        if (m_locked) {
-            m_locked = false;
-            g_mutex_unlock(&amp;m_mutex);
-        }
</del><ins>+        if (!m_locked)
+            return;
+
+        m_locked = false;
+        MutexWrapper&lt;T&gt;::unlock(&amp;m_mutex);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    GMutex&amp; m_mutex;
</del><ins>+    T&amp; m_mutex;
</ins><span class="cx">     bool m_locked;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWTFwtfgobjectGThreadSafeMainLoopSourcecpp"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.cpp (0 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.cpp                                (rev 0)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.cpp        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -0,0 +1,173 @@
</span><ins>+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;GThreadSafeMainLoopSource.h&quot;
+
+#if USE(GLIB)
+
+#include &lt;gio/gio.h&gt;
+#include &lt;wtf/gobject/GMutexLocker.h&gt;
+
+namespace WTF {
+
+GThreadSafeMainLoopSource::GThreadSafeMainLoopSource()
+{
+    g_rec_mutex_init(&amp;m_mutex);
+}
+
+GThreadSafeMainLoopSource::~GThreadSafeMainLoopSource()
+{
+    cancel();
+    g_rec_mutex_clear(&amp;m_mutex);
+}
+
+void GThreadSafeMainLoopSource::cancel()
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+
+    // The general cancellable object should only be present if we're currently dispatching this GMainLoopSource.
+    ASSERT(!m_cancellable || m_status == Dispatching);
+
+    // The source is perhaps being cancelled in the middle of a callback dispatch.
+    // Cancelling this GCancellable object will convey this information to the
+    // current execution context when the callback dispatch is finished.
+    g_cancellable_cancel(m_cancellable.get());
+    m_cancellable = nullptr;
+
+    GMainLoopSource::cancel();
+}
+
+void GThreadSafeMainLoopSource::schedule(const char* name, std::function&lt;void ()&gt; function, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    GMainLoopSource::schedule(name, function, priority, destroyFunction, context);
+    m_context.cancellable = adoptGRef(g_cancellable_new());
+}
+
+void GThreadSafeMainLoopSource::schedule(const char* name, std::function&lt;bool ()&gt; function, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    GMainLoopSource::schedule(name, function, priority, destroyFunction, context);
+    m_context.cancellable = adoptGRef(g_cancellable_new());
+}
+
+void GThreadSafeMainLoopSource::scheduleAfterDelay(const char* name, std::function&lt;void ()&gt; function, std::chrono::milliseconds delay, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    GMainLoopSource::scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
+    m_context.cancellable = adoptGRef(g_cancellable_new());
+}
+
+void GThreadSafeMainLoopSource::scheduleAfterDelay(const char* name, std::function&lt;bool ()&gt; function, std::chrono::milliseconds delay, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    GMainLoopSource::scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
+    m_context.cancellable = adoptGRef(g_cancellable_new());
+}
+
+void GThreadSafeMainLoopSource::scheduleAfterDelay(const char* name, std::function&lt;void ()&gt; function, std::chrono::seconds delay, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    GMainLoopSource::scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
+    m_context.cancellable = adoptGRef(g_cancellable_new());
+}
+
+void GThreadSafeMainLoopSource::scheduleAfterDelay(const char* name, std::function&lt;bool ()&gt; function, std::chrono::seconds delay, int priority, std::function&lt;void ()&gt; destroyFunction, GMainContext* context)
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    GMainLoopSource::scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
+    m_context.cancellable = adoptGRef(g_cancellable_new());
+}
+
+bool GThreadSafeMainLoopSource::prepareVoidCallback(Context&amp; context)
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    bool retval = GMainLoopSource::prepareVoidCallback(context);
+    m_cancellable = context.cancellable;
+    return retval;
+}
+
+void GThreadSafeMainLoopSource::finishVoidCallback()
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    GMainLoopSource::finishVoidCallback();
+    m_cancellable = nullptr;
+}
+
+void GThreadSafeMainLoopSource::voidCallback()
+{
+    Context context;
+    if (!prepareVoidCallback(context))
+        return;
+
+    context.voidCallback();
+
+    if (g_cancellable_is_cancelled(context.cancellable.get())) {
+        context.destroySource();
+        return;
+    }
+
+    finishVoidCallback();
+    context.destroySource();
+}
+
+bool GThreadSafeMainLoopSource::prepareBoolCallback(Context&amp; context)
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    bool retval = GMainLoopSource::prepareBoolCallback(context);
+    m_cancellable = context.cancellable;
+    return retval;
+}
+
+void GThreadSafeMainLoopSource::finishBoolCallback(bool retval, Context&amp; context)
+{
+    GMutexLocker&lt;GRecMutex&gt; locker(m_mutex);
+    GMainLoopSource::finishBoolCallback(retval, context);
+    m_cancellable = nullptr;
+}
+
+bool GThreadSafeMainLoopSource::boolCallback()
+{
+    Context context;
+    if (!prepareBoolCallback(context))
+        return Stop;
+
+    bool retval = context.boolCallback();
+
+    if (g_cancellable_is_cancelled(context.cancellable.get())) {
+        context.destroySource();
+        return Stop;
+    }
+
+    finishBoolCallback(retval, context);
+    if (context.source)
+        context.destroySource();
+    return retval;
+}
+
+} // namespace WTF
+
+#endif // USE(GLIB)
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWTFwtfgobjectGThreadSafeMainLoopSourceh"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.h (0 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.h                                (rev 0)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.h        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GThreadSafeMainLoopSource_h
+#define GThreadSafeMainLoopSource_h
+
+#if USE(GLIB)
+
+#include &lt;wtf/gobject/GMainLoopSource.h&gt;
+
+typedef struct _GRecMutex GRecMutex;
+
+namespace WTF {
+
+class GThreadSafeMainLoopSource final : public GMainLoopSource {
+    WTF_MAKE_NONCOPYABLE(GThreadSafeMainLoopSource);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    WTF_EXPORT_PRIVATE GThreadSafeMainLoopSource();
+    WTF_EXPORT_PRIVATE virtual ~GThreadSafeMainLoopSource();
+
+    WTF_EXPORT_PRIVATE virtual void schedule(const char* name, std::function&lt;void()&gt;, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr) override;
+    WTF_EXPORT_PRIVATE virtual void schedule(const char* name, std::function&lt;bool()&gt;, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr) override;
+    WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function&lt;void()&gt;, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr) override;
+    WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function&lt;bool()&gt;, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr) override;
+    WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function&lt;void()&gt;, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr) override;
+    WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function&lt;bool()&gt;, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function&lt;void()&gt; destroyFunction = nullptr, GMainContext* = nullptr) override;
+    WTF_EXPORT_PRIVATE virtual void cancel() override;
+
+private:
+    virtual void voidCallback() override;
+    virtual bool boolCallback() override;
+
+    virtual bool prepareVoidCallback(Context&amp;) override;
+    virtual void finishVoidCallback() override;
+    virtual bool prepareBoolCallback(Context&amp;) override;
+    virtual void finishBoolCallback(bool retval, Context&amp;) override;
+
+    GRecMutex m_mutex;
+    GRefPtr&lt;GCancellable&gt; m_cancellable;
+};
+
+} // namespace WTF
+
+using WTF::GThreadSafeMainLoopSource;
+
+#endif // USE(GLIB)
+
+#endif // GThreadSafeMainLoopSource_h
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -1,3 +1,52 @@
</span><ins>+2014-10-11  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GLIB] Split GMainLoopSource moving thread safe implementation to its own class GThreadSafeMainLoopSource
+        https://bugs.webkit.org/show_bug.cgi?id=137485
+
+        Reviewed by Sergio Villar Senin.
+
+        Use GThreadSafeMainLoopSource for GStreamer sources, since they
+        can be used from different threads. Also update GMutexLocker
+        usages, since it's now a template.
+
+        * platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
+        (WebCore::AudioFileReader::createBus):
+        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
+        (WebCore::MediaPlayerPrivateGStreamerBase::updateTexture):
+        (WebCore::MediaPlayerPrivateGStreamerBase::triggerRepaint):
+        (WebCore::MediaPlayerPrivateGStreamerBase::paint):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
+        * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
+        * platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
+        (webkitVideoSinkTimeoutCallback):
+        (webkitVideoSinkRender):
+        (unlockBufferMutex):
+        (webkitVideoSinkUnlockStop):
+        (webkitVideoSinkStart):
+        * platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp:
+        * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
+        (webKitWebSrcGetProperty):
+        (webKitWebSrcStop):
+        (webKitWebSrcStart):
+        (webKitWebSrcChangeState):
+        (webKitWebSrcQueryWithParent):
+        (webKitWebSrcGetUri):
+        (webKitWebSrcSetUri):
+        (webKitWebSrcNeedDataMainCb):
+        (webKitWebSrcNeedDataCb):
+        (webKitWebSrcEnoughDataMainCb):
+        (webKitWebSrcEnoughDataCb):
+        (webKitWebSrcSeekDataCb):
+        (webKitWebSrcSetMediaPlayer):
+        (StreamingClient::createReadBuffer):
+        (StreamingClient::handleResponseReceived):
+        (StreamingClient::handleDataReceived):
+        (StreamingClient::handleNotifyFinished):
+        (ResourceHandleStreamingClient::wasBlocked):
+        (ResourceHandleStreamingClient::cannotShowURL):
+
</ins><span class="cx"> 2014-10-05  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Do not generate a symlink in derived sources for every header in WebCore/bindings/gobject
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreplatformaudiogstreamerAudioFileReaderGStreamercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -31,8 +31,8 @@
</span><span class="cx"> #include &lt;gst/gst.h&gt;
</span><span class="cx"> #include &lt;gst/pbutils/pbutils.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><del>-#include &lt;wtf/gobject/GMainLoopSource.h&gt;
</del><span class="cx"> #include &lt;wtf/gobject/GRefPtr.h&gt;
</span><ins>+#include &lt;wtf/gobject/GThreadSafeMainLoopSource.h&gt;
</ins><span class="cx"> #include &lt;wtf/gobject/GUniquePtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -334,7 +334,7 @@
</span><span class="cx">     m_loop = adoptGRef(g_main_loop_new(context.get(), FALSE));
</span><span class="cx"> 
</span><span class="cx">     // Start the pipeline processing just after the loop is started.
</span><del>-    GMainLoopSource source;
</del><ins>+    GThreadSafeMainLoopSource source;
</ins><span class="cx">     source.schedule(&quot;[WebKit] AudioFileReader::decodeAudioForBusCreation&quot;, std::function&lt;void()&gt;(std::bind(&amp;AudioFileReader::decodeAudioForBusCreation, this)), G_PRIORITY_DEFAULT, nullptr, context.get());
</span><span class="cx"> 
</span><span class="cx">     g_main_loop_run(m_loop.get());
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerInbandTextTrackPrivateGStreamerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> #include &quot;GRefPtrGStreamer.h&quot;
</span><span class="cx"> #include &quot;InbandTextTrackPrivate.h&quot;
</span><span class="cx"> #include &quot;TrackPrivateBaseGStreamer.h&quot;
</span><del>-#include &lt;wtf/gobject/GMainLoopSource.h&gt;
</del><ins>+#include &lt;wtf/gobject/GThreadSafeMainLoopSource.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -62,8 +62,8 @@
</span><span class="cx"> private:
</span><span class="cx">     InbandTextTrackPrivateGStreamer(gint index, GRefPtr&lt;GstPad&gt;);
</span><span class="cx"> 
</span><del>-    GMainLoopSource m_sampleTimerHandler;
-    GMainLoopSource m_streamTimerHandler;
</del><ins>+    GThreadSafeMainLoopSource m_sampleTimerHandler;
+    GThreadSafeMainLoopSource m_streamTimerHandler;
</ins><span class="cx">     gulong m_eventProbe;
</span><span class="cx">     Vector&lt;GRefPtr&lt;GstSample&gt; &gt; m_pendingSamples;
</span><span class="cx">     String m_streamId;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> #include &lt;gst/gst.h&gt;
</span><span class="cx"> #include &lt;gst/pbutils/install-plugins.h&gt;
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><del>-#include &lt;wtf/gobject/GMainLoopSource.h&gt;
</del><ins>+#include &lt;wtf/gobject/GThreadSafeMainLoopSource.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO_TRACK) &amp;&amp; USE(GSTREAMER_MPEGTS)
</span><span class="cx"> #include &lt;wtf/text/AtomicStringHash.h&gt;
</span><span class="lines">@@ -202,11 +202,11 @@
</span><span class="cx">     bool m_volumeAndMuteInitialized;
</span><span class="cx">     bool m_hasVideo;
</span><span class="cx">     bool m_hasAudio;
</span><del>-    GMainLoopSource m_audioTimerHandler;
-    GMainLoopSource m_textTimerHandler;
-    GMainLoopSource m_videoTimerHandler;
-    GMainLoopSource m_videoCapsTimerHandler;
-    GMainLoopSource m_readyTimerHandler;
</del><ins>+    GThreadSafeMainLoopSource m_audioTimerHandler;
+    GThreadSafeMainLoopSource m_textTimerHandler;
+    GThreadSafeMainLoopSource m_videoTimerHandler;
+    GThreadSafeMainLoopSource m_videoCapsTimerHandler;
+    GThreadSafeMainLoopSource m_readyTimerHandler;
</ins><span class="cx">     mutable long m_totalBytes;
</span><span class="cx">     URL m_url;
</span><span class="cx">     bool m_preservesPitch;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerBasecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -275,7 +275,7 @@
</span><span class="cx"> #if USE(TEXTURE_MAPPER_GL) &amp;&amp; !USE(COORDINATED_GRAPHICS)
</span><span class="cx"> PassRefPtr&lt;BitmapTexture&gt; MediaPlayerPrivateGStreamerBase::updateTexture(TextureMapper* textureMapper)
</span><span class="cx"> {
</span><del>-    GMutexLocker lock(m_bufferMutex);
</del><ins>+    GMutexLocker&lt;GMutex&gt; lock(m_bufferMutex);
</ins><span class="cx">     if (!m_buffer)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="lines">@@ -325,7 +325,7 @@
</span><span class="cx">     g_return_if_fail(GST_IS_BUFFER(buffer));
</span><span class="cx"> 
</span><span class="cx">     {
</span><del>-        GMutexLocker lock(m_bufferMutex);
</del><ins>+        GMutexLocker&lt;GMutex&gt; lock(m_bufferMutex);
</ins><span class="cx">         gst_buffer_replace(&amp;m_buffer, buffer);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -357,7 +357,7 @@
</span><span class="cx">     if (!m_player-&gt;visible())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    GMutexLocker lock(m_bufferMutex);
</del><ins>+    GMutexLocker&lt;GMutex&gt; lock(m_bufferMutex);
</ins><span class="cx">     if (!m_buffer)
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerBaseh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -30,7 +30,7 @@
</span><span class="cx"> #include &lt;glib.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><del>-#include &lt;wtf/gobject/GMainLoopSource.h&gt;
</del><ins>+#include &lt;wtf/gobject/GThreadSafeMainLoopSource.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if USE(TEXTURE_MAPPER_GL) &amp;&amp; !USE(COORDINATED_GRAPHICS)
</span><span class="cx"> #include &quot;TextureMapperPlatformLayer.h&quot;
</span><span class="lines">@@ -125,8 +125,8 @@
</span><span class="cx">     IntSize m_size;
</span><span class="cx">     GMutex m_bufferMutex;
</span><span class="cx">     GstBuffer* m_buffer;
</span><del>-    GMainLoopSource m_volumeTimerHandler;
-    GMainLoopSource m_muteTimerHandler;
</del><ins>+    GThreadSafeMainLoopSource m_volumeTimerHandler;
+    GThreadSafeMainLoopSource m_muteTimerHandler;
</ins><span class="cx">     unsigned long m_repaintHandler;
</span><span class="cx">     unsigned long m_volumeSignalHandler;
</span><span class="cx">     unsigned long m_muteSignalHandler;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerTrackPrivateBaseGStreamerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -30,7 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;GRefPtrGStreamer.h&quot;
</span><span class="cx"> #include &lt;wtf/ThreadingPrimitives.h&gt;
</span><del>-#include &lt;wtf/gobject/GMainLoopSource.h&gt;
</del><ins>+#include &lt;wtf/gobject/GThreadSafeMainLoopSource.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -70,8 +70,8 @@
</span><span class="cx">     bool getTag(GstTagList* tags, const gchar* tagName, StringType&amp; value);
</span><span class="cx"> 
</span><span class="cx">     TrackPrivateBase* m_owner;
</span><del>-    GMainLoopSource m_activeTimerHandler;
-    GMainLoopSource m_tagTimerHandler;
</del><ins>+    GThreadSafeMainLoopSource m_activeTimerHandler;
+    GThreadSafeMainLoopSource m_tagTimerHandler;
</ins><span class="cx"> 
</span><span class="cx">     Mutex m_tagMutex;
</span><span class="cx">     GRefPtr&lt;GstTagList&gt; m_tags;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerVideoSinkGStreamercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -36,8 +36,8 @@
</span><span class="cx"> #include &lt;gst/gst.h&gt;
</span><span class="cx"> #include &lt;gst/video/gstvideometa.h&gt;
</span><span class="cx"> #include &lt;wtf/OwnPtr.h&gt;
</span><del>-#include &lt;wtf/gobject/GMainLoopSource.h&gt;
</del><span class="cx"> #include &lt;wtf/gobject/GMutexLocker.h&gt;
</span><ins>+#include &lt;wtf/gobject/GThreadSafeMainLoopSource.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><span class="lines">@@ -88,7 +88,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     GstBuffer* buffer;
</span><del>-    GMainLoopSource timeoutSource;
</del><ins>+    GThreadSafeMainLoopSource timeoutSource;
</ins><span class="cx">     GMutex bufferMutex;
</span><span class="cx">     GCond dataCondition;
</span><span class="cx"> 
</span><span class="lines">@@ -121,7 +121,7 @@
</span><span class="cx"> {
</span><span class="cx">     WebKitVideoSinkPrivate* priv = sink-&gt;priv;
</span><span class="cx"> 
</span><del>-    GMutexLocker lock(priv-&gt;bufferMutex);
</del><ins>+    GMutexLocker&lt;GMutex&gt; lock(priv-&gt;bufferMutex);
</ins><span class="cx">     GstBuffer* buffer = priv-&gt;buffer;
</span><span class="cx">     priv-&gt;buffer = 0;
</span><span class="cx"> 
</span><span class="lines">@@ -140,7 +140,7 @@
</span><span class="cx">     WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(baseSink);
</span><span class="cx">     WebKitVideoSinkPrivate* priv = sink-&gt;priv;
</span><span class="cx"> 
</span><del>-    GMutexLocker lock(priv-&gt;bufferMutex);
</del><ins>+    GMutexLocker&lt;GMutex&gt; lock(priv-&gt;bufferMutex);
</ins><span class="cx"> 
</span><span class="cx">     if (priv-&gt;unlocked)
</span><span class="cx">         return GST_FLOW_OK;
</span><span class="lines">@@ -257,7 +257,7 @@
</span><span class="cx"> 
</span><span class="cx"> static void unlockBufferMutex(WebKitVideoSinkPrivate* priv)
</span><span class="cx"> {
</span><del>-    GMutexLocker lock(priv-&gt;bufferMutex);
</del><ins>+    GMutexLocker&lt;GMutex&gt; lock(priv-&gt;bufferMutex);
</ins><span class="cx"> 
</span><span class="cx">     if (priv-&gt;buffer) {
</span><span class="cx">         gst_buffer_unref(priv-&gt;buffer);
</span><span class="lines">@@ -283,7 +283,7 @@
</span><span class="cx">     WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(baseSink)-&gt;priv;
</span><span class="cx"> 
</span><span class="cx">     {
</span><del>-        GMutexLocker lock(priv-&gt;bufferMutex);
</del><ins>+        GMutexLocker&lt;GMutex&gt; lock(priv-&gt;bufferMutex);
</ins><span class="cx">         priv-&gt;unlocked = false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -308,7 +308,7 @@
</span><span class="cx"> {
</span><span class="cx">     WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(baseSink)-&gt;priv;
</span><span class="cx"> 
</span><del>-    GMutexLocker lock(priv-&gt;bufferMutex);
</del><ins>+    GMutexLocker&lt;GMutex&gt; lock(priv-&gt;bufferMutex);
</ins><span class="cx">     priv-&gt;unlocked = false;
</span><span class="cx">     return TRUE;
</span><span class="cx"> }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerWebKitMediaSourceGStreamercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -30,7 +30,7 @@
</span><span class="cx"> #include &lt;gst/app/gstappsrc.h&gt;
</span><span class="cx"> #include &lt;gst/gst.h&gt;
</span><span class="cx"> #include &lt;gst/pbutils/missing-plugins.h&gt;
</span><del>-#include &lt;wtf/gobject/GMainLoopSource.h&gt;
</del><ins>+#include &lt;wtf/gobject/GThreadSafeMainLoopSource.h&gt;
</ins><span class="cx"> #include &lt;wtf/gobject/GUniquePtr.h&gt;
</span><span class="cx"> #include &lt;wtf/text/CString.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -44,11 +44,11 @@
</span><span class="cx">     guint64 size;
</span><span class="cx">     gboolean paused;
</span><span class="cx"> 
</span><del>-    GMainLoopSource start;
-    GMainLoopSource stop;
-    GMainLoopSource needData;
-    GMainLoopSource enoughData;
-    GMainLoopSource seek;
</del><ins>+    GThreadSafeMainLoopSource start;
+    GThreadSafeMainLoopSource stop;
+    GThreadSafeMainLoopSource needData;
+    GThreadSafeMainLoopSource enoughData;
+    GThreadSafeMainLoopSource seek;
</ins><span class="cx"> 
</span><span class="cx">     guint64 requestedOffset;
</span><span class="cx"> } Source;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreplatformgraphicsgstreamerWebKitWebSourceGStreamercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -43,9 +43,9 @@
</span><span class="cx"> #include &lt;gst/gst.h&gt;
</span><span class="cx"> #include &lt;gst/pbutils/missing-plugins.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><del>-#include &lt;wtf/gobject/GMainLoopSource.h&gt;
</del><span class="cx"> #include &lt;wtf/gobject/GMutexLocker.h&gt;
</span><span class="cx"> #include &lt;wtf/gobject/GRefPtr.h&gt;
</span><ins>+#include &lt;wtf/gobject/GThreadSafeMainLoopSource.h&gt;
</ins><span class="cx"> #include &lt;wtf/gobject/GUniquePtr.h&gt;
</span><span class="cx"> #include &lt;wtf/text/CString.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -139,11 +139,11 @@
</span><span class="cx"> 
</span><span class="cx">     guint64 requestedOffset;
</span><span class="cx"> 
</span><del>-    GMainLoopSource startSource;
-    GMainLoopSource stopSource;
-    GMainLoopSource needDataSource;
-    GMainLoopSource enoughDataSource;
-    GMainLoopSource seekSource;
</del><ins>+    GThreadSafeMainLoopSource startSource;
+    GThreadSafeMainLoopSource stopSource;
+    GThreadSafeMainLoopSource needDataSource;
+    GThreadSafeMainLoopSource enoughDataSource;
+    GThreadSafeMainLoopSource seekSource;
</ins><span class="cx"> 
</span><span class="cx">     GRefPtr&lt;GstBuffer&gt; buffer;
</span><span class="cx"> 
</span><span class="lines">@@ -352,7 +352,7 @@
</span><span class="cx">     WebKitWebSrc* src = WEBKIT_WEB_SRC(object);
</span><span class="cx">     WebKitWebSrcPrivate* priv = src-&gt;priv;
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     switch (propID) {
</span><span class="cx">     case PROP_IRADIO_NAME:
</span><span class="cx">         g_value_set_string(value, priv-&gt;iradioName);
</span><span class="lines">@@ -391,7 +391,7 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx"> 
</span><span class="cx">     bool seeking = priv-&gt;seekSource.isActive();
</span><span class="cx"> 
</span><span class="lines">@@ -447,7 +447,7 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx"> 
</span><span class="cx">     priv-&gt;corsAccessCheck = CORSNoCheck;
</span><span class="cx"> 
</span><span class="lines">@@ -539,7 +539,7 @@
</span><span class="cx">         return ret;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     switch (transition) {
</span><span class="cx">     case GST_STATE_CHANGE_READY_TO_PAUSED:
</span><span class="cx">         GST_DEBUG_OBJECT(src, &quot;READY-&gt;PAUSED&quot;);
</span><span class="lines">@@ -574,7 +574,7 @@
</span><span class="cx">         gst_query_parse_duration(query, &amp;format, NULL);
</span><span class="cx"> 
</span><span class="cx">         GST_DEBUG_OBJECT(src, &quot;duration query in format %s&quot;, gst_format_get_name(format));
</span><del>-        GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+        GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">         if (format == GST_FORMAT_BYTES &amp;&amp; src-&gt;priv-&gt;size &gt; 0) {
</span><span class="cx">             gst_query_set_duration(query, format, src-&gt;priv-&gt;size);
</span><span class="cx">             result = TRUE;
</span><span class="lines">@@ -582,7 +582,7 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case GST_QUERY_URI: {
</span><del>-        GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+        GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">         gst_query_set_uri(query, src-&gt;priv-&gt;uri);
</span><span class="cx">         result = TRUE;
</span><span class="cx">         break;
</span><span class="lines">@@ -623,7 +623,7 @@
</span><span class="cx">     WebKitWebSrc* src = WEBKIT_WEB_SRC(handler);
</span><span class="cx">     gchar* ret;
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     ret = g_strdup(src-&gt;priv-&gt;uri);
</span><span class="cx">     return ret;
</span><span class="cx"> }
</span><span class="lines">@@ -638,7 +638,7 @@
</span><span class="cx">         return FALSE;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx"> 
</span><span class="cx">     g_free(priv-&gt;uri);
</span><span class="cx">     priv-&gt;uri = 0;
</span><span class="lines">@@ -674,7 +674,7 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     priv-&gt;paused = FALSE;
</span><span class="cx">     locker.unlock();
</span><span class="cx"> 
</span><span class="lines">@@ -689,7 +689,7 @@
</span><span class="cx"> 
</span><span class="cx">     GST_DEBUG_OBJECT(src, &quot;Need more data: %u&quot;, length);
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     if (priv-&gt;needDataSource.isScheduled() || !priv-&gt;paused)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -704,7 +704,7 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     priv-&gt;paused = TRUE;
</span><span class="cx">     locker.unlock();
</span><span class="cx"> 
</span><span class="lines">@@ -719,7 +719,7 @@
</span><span class="cx"> 
</span><span class="cx">     GST_DEBUG_OBJECT(src, &quot;Have enough data&quot;);
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     if (priv-&gt;enoughDataSource.isScheduled() || priv-&gt;paused)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -742,7 +742,7 @@
</span><span class="cx">     WebKitWebSrcPrivate* priv = src-&gt;priv;
</span><span class="cx"> 
</span><span class="cx">     GST_DEBUG_OBJECT(src, &quot;Seeking to offset: %&quot; G_GUINT64_FORMAT, offset);
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     if (offset == priv-&gt;offset &amp;&amp; priv-&gt;requestedOffset == priv-&gt;offset)
</span><span class="cx">         return TRUE;
</span><span class="cx"> 
</span><span class="lines">@@ -761,7 +761,7 @@
</span><span class="cx"> void webKitWebSrcSetMediaPlayer(WebKitWebSrc* src, WebCore::MediaPlayer* player)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(player);
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     src-&gt;priv-&gt;player = player;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -791,7 +791,7 @@
</span><span class="cx"> 
</span><span class="cx">     mapGstBuffer(buffer);
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     priv-&gt;buffer = adoptGRef(buffer);
</span><span class="cx">     locker.unlock();
</span><span class="cx"> 
</span><span class="lines">@@ -817,7 +817,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx"> 
</span><span class="cx">     priv-&gt;corsAccessCheck = corsAccessCheck;
</span><span class="cx"> 
</span><span class="lines">@@ -916,7 +916,7 @@
</span><span class="cx">     WebKitWebSrc* src = WEBKIT_WEB_SRC(m_src);
</span><span class="cx">     WebKitWebSrcPrivate* priv = src-&gt;priv;
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx"> 
</span><span class="cx">     GST_LOG_OBJECT(src, &quot;Have %lld bytes of data&quot;, priv-&gt;buffer ? static_cast&lt;long long&gt;(gst_buffer_get_size(priv-&gt;buffer.get())) : length);
</span><span class="cx"> 
</span><span class="lines">@@ -985,7 +985,7 @@
</span><span class="cx"> 
</span><span class="cx">     GST_DEBUG_OBJECT(src, &quot;Have EOS&quot;);
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     if (!priv-&gt;seekSource.isActive()) {
</span><span class="cx">         locker.unlock();
</span><span class="cx">         gst_app_src_end_of_stream(priv-&gt;appsrc);
</span><span class="lines">@@ -1144,7 +1144,7 @@
</span><span class="cx"> 
</span><span class="cx">     GST_ERROR_OBJECT(src, &quot;Request was blocked&quot;);
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     uri.reset(g_strdup(src-&gt;priv-&gt;uri));
</span><span class="cx">     locker.unlock();
</span><span class="cx"> 
</span><span class="lines">@@ -1158,7 +1158,7 @@
</span><span class="cx"> 
</span><span class="cx">     GST_ERROR_OBJECT(src, &quot;Cannot show URL&quot;);
</span><span class="cx"> 
</span><del>-    GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
</del><ins>+    GMutexLocker&lt;GMutex&gt; locker(*GST_OBJECT_GET_LOCK(src));
</ins><span class="cx">     uri.reset(g_strdup(src-&gt;priv-&gt;uri));
</span><span class="cx">     locker.unlock();
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26ToolsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Tools/ChangeLog (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Tools/ChangeLog        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Tools/ChangeLog        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2014-10-11  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GLIB] Split GMainLoopSource moving thread safe implementation to its own class GThreadSafeMainLoopSource
+        https://bugs.webkit.org/show_bug.cgi?id=137485
+
+        Reviewed by Sergio Villar Senin.
+
+        Update GMainLoopSource tests. Most of the tests are now run twice,
+        first with a GMainLoopSource and then with a
+        GThreadSafeMainLoopSource, since both should have the same
+        behaviour. The threading test uses GThreadSafeMainLoopSource and
+        the delete on destroy test uses GMainLoopSource. The tests
+        themselves haven't changed, since there's no change in behaviour.
+
+        * TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp:
+        (TestWebKitAPI::GMainLoopSourceTest::source):
+        (TestWebKitAPI::basicRescheduling):
+        (TestWebKitAPI::TEST):
+        (TestWebKitAPI::reentrantRescheduling):
+        (TestWebKitAPI::cancelRepeatingSourceDuringDispatch):
+        (TestWebKitAPI::basicDestroyCallbacks):
+        (TestWebKitAPI::destroyCallbacksAfterCancellingDuringDispatch):
+        (TestWebKitAPI::destroyCallbacksAfterReschedulingDuringDispatch):
+
</ins><span class="cx"> 2014-10-08  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Make forwarding headers generation depend on source code
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26ToolsTestWebKitAPITestsWTFgobjectGMainLoopSourcecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Tools/TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp (174637 => 174638)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Tools/TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp        2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Tools/TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp        2014-10-12 09:18:47 UTC (rev 174638)
</span><span class="lines">@@ -19,11 +19,12 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> 
</span><del>-#include &lt;wtf/gobject/GMainLoopSource.h&gt;
</del><ins>+#include &lt;wtf/gobject/GThreadSafeMainLoopSource.h&gt;
</ins><span class="cx"> #include &lt;stdio.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace TestWebKitAPI {
</span><span class="cx"> 
</span><ins>+template &lt;typename T&gt;
</ins><span class="cx"> class GMainLoopSourceTest {
</span><span class="cx"> public:
</span><span class="cx">     GMainLoopSourceTest()
</span><span class="lines">@@ -56,21 +57,16 @@
</span><span class="cx">         g_main_loop_quit(m_mainLoop);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    GMainLoopSource&amp; source() { return m_source; }
</del><ins>+    T&amp; source() { return m_source; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     GMainLoop* m_mainLoop;
</span><del>-    GMainLoopSource m_source;
</del><ins>+    T m_source;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-TEST(WTF_GMainLoopSource, BasicRescheduling)
</del><ins>+template &lt;typename T&gt;
+static void basicRescheduling(T&amp; context)
</ins><span class="cx"> {
</span><del>-    struct TestingContext {
-        GMainLoopSourceTest test;
-        bool finishedFirstTask = false;
-        bool finishedSecondTask = false;
-    } context;
-
</del><span class="cx">     EXPECT_TRUE(!context.test.source().isActive());
</span><span class="cx"> 
</span><span class="cx">     context.test.source().schedule(&quot;[Test] FirstTask&quot;, [&amp;] {
</span><span class="lines">@@ -94,14 +90,26 @@
</span><span class="cx">     EXPECT_TRUE(context.finishedSecondTask);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TEST(WTF_GMainLoopSource, ReentrantRescheduling)
</del><ins>+TEST(WTF_GMainLoopSource, BasicRescheduling)
</ins><span class="cx"> {
</span><span class="cx">     struct TestingContext {
</span><del>-        GMainLoopSourceTest test;
</del><ins>+        GMainLoopSourceTest&lt;GMainLoopSource&gt; test;
</ins><span class="cx">         bool finishedFirstTask = false;
</span><span class="cx">         bool finishedSecondTask = false;
</span><span class="cx">     } context;
</span><ins>+    basicRescheduling&lt;TestingContext&gt;(context);
</ins><span class="cx"> 
</span><ins>+    struct ThreadSafeTestingContext {
+        GMainLoopSourceTest&lt;GThreadSafeMainLoopSource&gt; test;
+        bool finishedFirstTask = false;
+        bool finishedSecondTask = false;
+    } threadSafeContext;
+    basicRescheduling&lt;ThreadSafeTestingContext&gt;(threadSafeContext);
+}
+
+template &lt;typename T&gt;
+static void reentrantRescheduling(T&amp; context)
+{
</ins><span class="cx">     EXPECT_TRUE(!context.test.source().isActive());
</span><span class="cx"> 
</span><span class="cx">     context.test.source().schedule(&quot;[Test] FirstTask&quot;, [&amp;] {
</span><span class="lines">@@ -127,10 +135,27 @@
</span><span class="cx">     EXPECT_TRUE(context.finishedSecondTask);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TEST(WTF_GMainLoopSource, ReentrantRescheduling)
+{
+    struct TestingContext {
+        GMainLoopSourceTest&lt;GMainLoopSource&gt; test;
+        bool finishedFirstTask = false;
+        bool finishedSecondTask = false;
+    } context;
+    reentrantRescheduling&lt;TestingContext&gt;(context);
+
+    struct ThreadSafeTestingContext {
+        GMainLoopSourceTest&lt;GThreadSafeMainLoopSource&gt; test;
+        bool finishedFirstTask = false;
+        bool finishedSecondTask = false;
+    } threadSafeContext;
+    reentrantRescheduling&lt;ThreadSafeTestingContext&gt;(threadSafeContext);
+}
+
</ins><span class="cx"> TEST(WTF_GMainLoopSource, ReschedulingFromDifferentThread)
</span><span class="cx"> {
</span><span class="cx">     struct TestingContext {
</span><del>-        GMainLoopSourceTest test;
</del><ins>+        GMainLoopSourceTest&lt;GThreadSafeMainLoopSource&gt; test;
</ins><span class="cx">         bool finishedFirstTask;
</span><span class="cx">         bool finishedSecondTask;
</span><span class="cx">     } context;
</span><span class="lines">@@ -198,13 +223,9 @@
</span><span class="cx">     g_main_loop_unref(loop);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TEST(WTF_GMainLoopSource, CancelRepeatingSourceDuringDispatch)
</del><ins>+template &lt;typename T&gt;
+static void cancelRepeatingSourceDuringDispatch(T&amp; context)
</ins><span class="cx"> {
</span><del>-    struct TestingContext {
-        GMainLoopSourceTest test;
-        unsigned callCount = 0;
-    } context;
-
</del><span class="cx">     EXPECT_TRUE(!context.test.source().isActive());
</span><span class="cx"> 
</span><span class="cx">     context.test.source().schedule(&quot;[Test] RepeatingTask&quot;,
</span><span class="lines">@@ -225,16 +246,26 @@
</span><span class="cx">     EXPECT_EQ(3, context.callCount);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TEST(WTF_GMainLoopSource, BasicDestroyCallbacks)
</del><ins>+TEST(WTF_GMainLoopSource, CancelRepeatingSourceDuringDispatch)
</ins><span class="cx"> {
</span><span class="cx">     struct TestingContext {
</span><del>-        GMainLoopSourceTest test;
-        bool callbackCalled = false;
-        bool destroyCallbackCalled = false;
-    };
</del><ins>+        GMainLoopSourceTest&lt;GMainLoopSource&gt; test;
+        unsigned callCount = 0;
+    } context;
+    cancelRepeatingSourceDuringDispatch&lt;TestingContext&gt;(context);
</ins><span class="cx"> 
</span><ins>+    struct ThreadSafeTestingContext {
+        GMainLoopSourceTest&lt;GThreadSafeMainLoopSource&gt; test;
+        unsigned callCount = 0;
+    } threadSafeContext;
+    cancelRepeatingSourceDuringDispatch&lt;ThreadSafeTestingContext&gt;(threadSafeContext);
+}
+
+template &lt;typename T&gt;
+static void basicDestroyCallbacks()
+{
</ins><span class="cx">     {
</span><del>-        TestingContext context;
</del><ins>+        T context;
</ins><span class="cx">         EXPECT_TRUE(!context.test.source().isActive());
</span><span class="cx">         context.test.source().schedule(&quot;[Test] DestroyCallback&quot;,
</span><span class="cx">             [&amp;] {
</span><span class="lines">@@ -256,7 +287,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     {
</span><del>-        TestingContext context;
</del><ins>+        T context;
</ins><span class="cx">         EXPECT_TRUE(!context.test.source().isActive());
</span><span class="cx">         context.test.source().schedule(&quot;[Test] DestroyCallback&quot;,
</span><span class="cx">             std::function&lt;bool ()&gt;([&amp;] {
</span><span class="lines">@@ -279,16 +310,28 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TEST(WTF_GMainLoopSource, DestroyCallbacksAfterCancellingDuringDispatch)
</del><ins>+TEST(WTF_GMainLoopSource, BasicDestroyCallbacks)
</ins><span class="cx"> {
</span><span class="cx">     struct TestingContext {
</span><del>-        GMainLoopSourceTest test;
-        unsigned callbackCallCount= 0;
</del><ins>+        GMainLoopSourceTest&lt;GMainLoopSource&gt; test;
+        bool callbackCalled = false;
</ins><span class="cx">         bool destroyCallbackCalled = false;
</span><span class="cx">     };
</span><ins>+    basicDestroyCallbacks&lt;TestingContext&gt;();
</ins><span class="cx"> 
</span><ins>+    struct ThreadSafeTestingContext {
+        GMainLoopSourceTest&lt;GThreadSafeMainLoopSource&gt; test;
+        bool callbackCalled = false;
+        bool destroyCallbackCalled = false;
+    };
+    basicDestroyCallbacks&lt;ThreadSafeTestingContext&gt;();
+}
+
+template &lt;typename T&gt;
+static void destroyCallbacksAfterCancellingDuringDispatch()
+{
</ins><span class="cx">     {
</span><del>-        TestingContext context;
</del><ins>+        T context;
</ins><span class="cx">         EXPECT_TRUE(!context.test.source().isActive());
</span><span class="cx">         context.test.source().schedule(&quot;[Test] DestroyCallback&quot;,
</span><span class="cx">             [&amp;] {
</span><span class="lines">@@ -312,7 +355,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     {
</span><del>-        TestingContext context;
</del><ins>+        T context;
</ins><span class="cx">         EXPECT_TRUE(!context.test.source().isActive());
</span><span class="cx">         context.test.source().schedule(&quot;[Test] DestroyCallback&quot;,
</span><span class="cx">             std::function&lt;bool ()&gt;([&amp;] {
</span><span class="lines">@@ -337,18 +380,28 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TEST(WTF_GMainLoopSource, DestroyCallbacksAfterReschedulingDuringDispatch)
</del><ins>+TEST(WTF_GMainLoopSource, DestroyCallbacksAfterCancellingDuringDispatch)
</ins><span class="cx"> {
</span><span class="cx">     struct TestingContext {
</span><del>-        GMainLoopSourceTest test;
-        unsigned firstCallbackCallCount = 0;
-        bool firstDestroyCallbackCalled = false;
-        unsigned secondCallbackCallCount = 0;
-        bool secondDestroyCallbackCalled = false;
</del><ins>+        GMainLoopSourceTest&lt;GMainLoopSource&gt; test;
+        unsigned callbackCallCount= 0;
+        bool destroyCallbackCalled = false;
</ins><span class="cx">     };
</span><ins>+    destroyCallbacksAfterCancellingDuringDispatch&lt;TestingContext&gt;();
</ins><span class="cx"> 
</span><ins>+    struct ThreadSafeTestingContext {
+        GMainLoopSourceTest&lt;GThreadSafeMainLoopSource&gt; test;
+        unsigned callbackCallCount= 0;
+        bool destroyCallbackCalled = false;
+    };
+    destroyCallbacksAfterCancellingDuringDispatch&lt;ThreadSafeTestingContext&gt;();
+}
+
+template &lt;typename T&gt;
+static void destroyCallbacksAfterReschedulingDuringDispatch()
+{
</ins><span class="cx">     {
</span><del>-        TestingContext context;
</del><ins>+        T context;
</ins><span class="cx">         EXPECT_TRUE(!context.test.source().isActive());
</span><span class="cx">         context.test.source().schedule(&quot;[Test] BaseCallback&quot;,
</span><span class="cx">             [&amp;] {
</span><span class="lines">@@ -383,7 +436,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     {
</span><del>-        TestingContext context;
</del><ins>+        T context;
</ins><span class="cx">         EXPECT_TRUE(!context.test.source().isActive());
</span><span class="cx">         context.test.source().schedule(&quot;[Test] BaseCallback&quot;,
</span><span class="cx">             std::function&lt;bool ()&gt;([&amp;] {
</span><span class="lines">@@ -420,6 +473,27 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TEST(WTF_GMainLoopSource, DestroyCallbacksAfterReschedulingDuringDispatch)
+{
+    struct TestingContext {
+        GMainLoopSourceTest&lt;GMainLoopSource&gt; test;
+        unsigned firstCallbackCallCount = 0;
+        bool firstDestroyCallbackCalled = false;
+        unsigned secondCallbackCallCount = 0;
+        bool secondDestroyCallbackCalled = false;
+    };
+    destroyCallbacksAfterReschedulingDuringDispatch&lt;TestingContext&gt;();
+
+    struct ThreadSafeTestingContext {
+        GMainLoopSourceTest&lt;GThreadSafeMainLoopSource&gt; test;
+        unsigned firstCallbackCallCount = 0;
+        bool firstDestroyCallbackCalled = false;
+        unsigned secondCallbackCallCount = 0;
+        bool secondDestroyCallbackCalled = false;
+    };
+    destroyCallbacksAfterReschedulingDuringDispatch&lt;ThreadSafeTestingContext&gt;();
+}
+
</ins><span class="cx"> TEST(WTF_GMainLoopSource, DeleteOnDestroySources)
</span><span class="cx"> {
</span><span class="cx">     // Testing the delete-on-destroy sources is very limited. There's no good way
</span><span class="lines">@@ -427,7 +501,7 @@
</span><span class="cx">     // is destroyed.
</span><span class="cx"> 
</span><span class="cx">     struct TestingContext {
</span><del>-        GMainLoopSourceTest test;
</del><ins>+        GMainLoopSourceTest&lt;GMainLoopSource&gt; test;
</ins><span class="cx">         unsigned callbackCallCount = 0;
</span><span class="cx">         bool destroyCallbackCalled = false;
</span><span class="cx">     } context;
</span></span></pre>
</div>
</div>

</body>
</html>