<!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>[169375] releases/WebKitGTK/webkit-2.4</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/169375">169375</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2014-05-27 02:43:04 -0700 (Tue, 27 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/169352">r169352</a> - [GTK] WebProcess leaked when closing pages with network process enabled
https://bugs.webkit.org/show_bug.cgi?id=129684

Reviewed by Anders Carlsson.

Source/WebKit2:
The problem is that the web process is not notified when the UI
process closes the connection, because when close() is called on
the socket by the UI process, the socket is shared by another web
process launched later, preventing the connection from being
shut down. We need to set the CLOEXEC flag on the sockets file
descriptor to make sure they are not exposed to other processes.

* Platform/IPC/Connection.h: Add ConnectionOptions parameter to
createPlatformConnection() with a default value compatible with
existing callers.
* Platform/IPC/unix/ConnectionUnix.cpp:
(IPC::Connection::createPlatformConnection): Set the CLOEXEC flag
on the client and server socket file descriptors depending on the
options passed.
* UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp:
(WebKit::ProcessLauncher::launchProcess): Use
IPC::Connection::createPlatformConnection() instead of
socketpair() directly, setting the CLOEXEC flag on the server
before spawning the new process and on the client right after
spawning the new process.

Tools:
Enable the test to check that web processes finish when the web
view is destroyed.

* TestWebKitAPI/Tests/WebKit2Gtk/TestMultiprocess.cpp:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit24SourceWebKit2ChangeLog">releases/WebKitGTK/webkit-2.4/Source/WebKit2/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit24SourceWebKit2PlatformIPCConnectionh">releases/WebKitGTK/webkit-2.4/Source/WebKit2/Platform/IPC/Connection.h</a></li>
<li><a href="#releasesWebKitGTKwebkit24SourceWebKit2PlatformIPCunixConnectionUnixcpp">releases/WebKitGTK/webkit-2.4/Source/WebKit2/Platform/IPC/unix/ConnectionUnix.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit24SourceWebKit2UIProcessLaunchergtkProcessLauncherGtkcpp">releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit24ToolsChangeLog">releases/WebKitGTK/webkit-2.4/Tools/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit24ToolsTestWebKitAPITestsWebKit2GtkTestMultiprocesscpp">releases/WebKitGTK/webkit-2.4/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestMultiprocess.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit24SourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/ChangeLog (169374 => 169375)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/ChangeLog        2014-05-27 09:06:11 UTC (rev 169374)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/ChangeLog        2014-05-27 09:43:04 UTC (rev 169375)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2014-05-26  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GTK] WebProcess leaked when closing pages with network process enabled
+        https://bugs.webkit.org/show_bug.cgi?id=129684
+
+        Reviewed by Anders Carlsson.
+
+        The problem is that the web process is not notified when the UI
+        process closes the connection, because when close() is called on
+        the socket by the UI process, the socket is shared by another web
+        process launched later, preventing the connection from being
+        shut down. We need to set the CLOEXEC flag on the sockets file
+        descriptor to make sure they are not exposed to other processes.
+
+        * Platform/IPC/Connection.h: Add ConnectionOptions parameter to
+        createPlatformConnection() with a default value compatible with
+        existing callers.
+        * Platform/IPC/unix/ConnectionUnix.cpp:
+        (IPC::Connection::createPlatformConnection): Set the CLOEXEC flag
+        on the client and server socket file descriptors depending on the
+        options passed.
+        * UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp:
+        (WebKit::ProcessLauncher::launchProcess): Use
+        IPC::Connection::createPlatformConnection() instead of
+        socketpair() directly, setting the CLOEXEC flag on the server
+        before spawning the new process and on the client right after
+        spawning the new process.
+
</ins><span class="cx"> 2014-05-20  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] WebKitWebPage::send-request always pass a valid pointer for redirected response
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit24SourceWebKit2PlatformIPCConnectionh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/Platform/IPC/Connection.h (169374 => 169375)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/Platform/IPC/Connection.h        2014-05-27 09:06:11 UTC (rev 169374)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/Platform/IPC/Connection.h        2014-05-27 09:43:04 UTC (rev 169375)
</span><span class="lines">@@ -122,7 +122,12 @@
</span><span class="cx">         int server;
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    static Connection::SocketPair createPlatformConnection();
</del><ins>+    enum ConnectionOptions {
+        SetCloexecOnClient = 1 &lt;&lt; 0,
+        SetCloexecOnServer = 1 &lt;&lt; 1,
+    };
+
+    static Connection::SocketPair createPlatformConnection(unsigned options = SetCloexecOnClient | SetCloexecOnServer);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     static PassRefPtr&lt;Connection&gt; createServerConnection(Identifier, Client*, WTF::RunLoop* clientRunLoop);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit24SourceWebKit2PlatformIPCunixConnectionUnixcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/Platform/IPC/unix/ConnectionUnix.cpp (169374 => 169375)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/Platform/IPC/unix/ConnectionUnix.cpp        2014-05-27 09:06:11 UTC (rev 169374)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/Platform/IPC/unix/ConnectionUnix.cpp        2014-05-27 09:43:04 UTC (rev 169375)
</span><span class="lines">@@ -541,18 +541,22 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Connection::SocketPair Connection::createPlatformConnection()
</del><ins>+Connection::SocketPair Connection::createPlatformConnection(unsigned options)
</ins><span class="cx"> {
</span><span class="cx">     int sockets[2];
</span><span class="cx">     RELEASE_ASSERT(socketpair(AF_UNIX, SOCKET_TYPE, 0, sockets) != -1);
</span><span class="cx"> 
</span><del>-    // Don't expose the child socket to the parent process.
-    while (fcntl(sockets[1], F_SETFD, FD_CLOEXEC)  == -1)
-        RELEASE_ASSERT(errno != EINTR);
</del><ins>+    if (options &amp; SetCloexecOnServer) {
+        // Don't expose the child socket to the parent process.
+        while (fcntl(sockets[1], F_SETFD, FD_CLOEXEC)  == -1)
+            RELEASE_ASSERT(errno != EINTR);
+    }
</ins><span class="cx"> 
</span><del>-    // Don't expose the parent socket to potential future children.
-    while (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1)
-        RELEASE_ASSERT(errno != EINTR);
</del><ins>+    if (options &amp; SetCloexecOnClient) {
+        // Don't expose the parent socket to potential future children.
+        while (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1)
+            RELEASE_ASSERT(errno != EINTR);
+    }
</ins><span class="cx"> 
</span><span class="cx">     SocketPair socketPair = { sockets[0], sockets[1] };
</span><span class="cx">     return socketPair;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit24SourceWebKit2UIProcessLaunchergtkProcessLauncherGtkcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp (169374 => 169375)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp        2014-05-27 09:06:11 UTC (rev 169374)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp        2014-05-27 09:43:04 UTC (rev 169375)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include &lt;WebCore/NetworkingContext.h&gt;
</span><span class="cx"> #include &lt;WebCore/ResourceHandle.h&gt;
</span><span class="cx"> #include &lt;errno.h&gt;
</span><ins>+#include &lt;fcntl.h&gt;
</ins><span class="cx"> #include &lt;glib.h&gt;
</span><span class="cx"> #include &lt;locale.h&gt;
</span><span class="cx"> #include &lt;wtf/RunLoop.h&gt;
</span><span class="lines">@@ -42,16 +43,6 @@
</span><span class="cx"> #include &lt;wtf/gobject/GUniquePtr.h&gt;
</span><span class="cx"> #include &lt;wtf/gobject/GlibUtilities.h&gt;
</span><span class="cx"> 
</span><del>-#if OS(UNIX)
-#include &lt;sys/socket.h&gt;
-#endif
-
-#ifdef SOCK_SEQPACKET
-#define SOCKET_TYPE SOCK_SEQPACKET
-#else
-#define SOCKET_TYPE SOCK_STREAM
-#endif
-
</del><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="lines">@@ -66,12 +57,7 @@
</span><span class="cx"> {
</span><span class="cx">     GPid pid = 0;
</span><span class="cx"> 
</span><del>-    int sockets[2];
-    if (socketpair(AF_UNIX, SOCKET_TYPE, 0, sockets) &lt; 0) {
-        g_printerr(&quot;Creation of socket failed: %s.\n&quot;, g_strerror(errno));
-        ASSERT_NOT_REACHED();
-        return;
-    }
</del><ins>+    IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection(IPC::Connection::ConnectionOptions::SetCloexecOnServer);
</ins><span class="cx"> 
</span><span class="cx">     String executablePath, pluginPath;
</span><span class="cx">     CString realExecutablePath, realPluginPath;
</span><span class="lines">@@ -95,7 +81,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     realExecutablePath = fileSystemRepresentation(executablePath);
</span><del>-    GUniquePtr&lt;gchar&gt; socket(g_strdup_printf(&quot;%d&quot;, sockets[0]));
</del><ins>+    GUniquePtr&lt;gchar&gt; socket(g_strdup_printf(&quot;%d&quot;, socketPair.client));
</ins><span class="cx"> 
</span><span class="cx">     unsigned nargs = 4; // size of the argv array for g_spawn_async()
</span><span class="cx"> 
</span><span class="lines">@@ -123,16 +109,20 @@
</span><span class="cx">     argv[i++] = 0;
</span><span class="cx"> 
</span><span class="cx">     GUniqueOutPtr&lt;GError&gt; error;
</span><del>-    if (!g_spawn_async(0, argv, 0, G_SPAWN_LEAVE_DESCRIPTORS_OPEN, childSetupFunction, GINT_TO_POINTER(sockets[1]), &amp;pid, &amp;error.outPtr())) {
</del><ins>+    if (!g_spawn_async(0, argv, 0, G_SPAWN_LEAVE_DESCRIPTORS_OPEN, childSetupFunction, GINT_TO_POINTER(socketPair.server), &amp;pid, &amp;error.outPtr())) {
</ins><span class="cx">         g_printerr(&quot;Unable to fork a new WebProcess: %s.\n&quot;, error-&gt;message);
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    close(sockets[0]);
</del><ins>+    // Don't expose the parent socket to potential future children.
+    while (fcntl(socketPair.client, F_SETFD, FD_CLOEXEC) == -1)
+        RELEASE_ASSERT(errno != EINTR);
+
+    close(socketPair.client);
</ins><span class="cx">     m_processIdentifier = pid;
</span><span class="cx"> 
</span><span class="cx">     // We've finished launching the process, message back to the main run loop.
</span><del>-    RunLoop::main()-&gt;dispatch(bind(&amp;ProcessLauncher::didFinishLaunchingProcess, this, m_processIdentifier, sockets[1]));
</del><ins>+    RunLoop::main()-&gt;dispatch(bind(&amp;ProcessLauncher::didFinishLaunchingProcess, this, m_processIdentifier, socketPair.server));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ProcessLauncher::terminateProcess()
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit24ToolsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.4/Tools/ChangeLog (169374 => 169375)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.4/Tools/ChangeLog        2014-05-27 09:06:11 UTC (rev 169374)
+++ releases/WebKitGTK/webkit-2.4/Tools/ChangeLog        2014-05-27 09:43:04 UTC (rev 169375)
</span><span class="lines">@@ -1,5 +1,17 @@
</span><span class="cx"> 2014-05-26  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><ins>+        [GTK] WebProcess leaked when closing pages with network process enabled
+        https://bugs.webkit.org/show_bug.cgi?id=129684
+
+        Reviewed by Anders Carlsson.
+
+        Enable the test to check that web processes finish when the web
+        view is destroyed.
+
+        * TestWebKitAPI/Tests/WebKit2Gtk/TestMultiprocess.cpp:
+
+2014-05-26  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
</ins><span class="cx">         Unreviewed. Fix make distcheck.
</span><span class="cx"> 
</span><span class="cx">         * gtk/GNUmakefile.am: Remove generate-webkitdom-doc-files from
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit24ToolsTestWebKitAPITestsWebKit2GtkTestMultiprocesscpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.4/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestMultiprocess.cpp (169374 => 169375)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.4/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestMultiprocess.cpp        2014-05-27 09:06:11 UTC (rev 169374)
+++ releases/WebKitGTK/webkit-2.4/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestMultiprocess.cpp        2014-05-27 09:43:04 UTC (rev 169375)
</span><span class="lines">@@ -90,7 +90,6 @@
</span><span class="cx">     {
</span><span class="cx">         // FIXME: This test is disabled because the web processed don't actually die
</span><span class="cx">         // due to bug https://bugs.webkit.org/show_bug.cgi?id=129684.
</span><del>-#if 0
</del><span class="cx">         g_assert_cmpuint(index, &lt;, numViews);
</span><span class="cx"> 
</span><span class="cx">         unsigned watcherID = g_bus_watch_name_on_connection(bus-&gt;connection(), m_webViewBusNames[index].get(), G_BUS_NAME_WATCHER_FLAGS_NONE,
</span><span class="lines">@@ -98,7 +97,6 @@
</span><span class="cx">         gtk_widget_destroy(GTK_WIDGET(m_webViews[index].get()));
</span><span class="cx">         g_main_loop_run(m_mainLoop);
</span><span class="cx">         g_bus_unwatch_name(watcherID);
</span><del>-#endif
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     GMainLoop* m_mainLoop;
</span></span></pre>
</div>
</div>

</body>
</html>