summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/Launcher
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
commit40736c5763bf61337c8c14e16d8587db021a87d4 (patch)
treeb17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebKit2/UIProcess/Launcher
downloadqtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebKit2/UIProcess/Launcher')
-rw-r--r--Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp97
-rw-r--r--Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h95
-rw-r--r--Source/WebKit2/UIProcess/Launcher/ThreadLauncher.cpp66
-rw-r--r--Source/WebKit2/UIProcess/Launcher/ThreadLauncher.h71
-rw-r--r--Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp151
-rw-r--r--Source/WebKit2/UIProcess/Launcher/gtk/ThreadLauncherGtk.cpp40
-rw-r--r--Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.h66
-rw-r--r--Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm204
-rw-r--r--Source/WebKit2/UIProcess/Launcher/mac/EnvironmentVariables.cpp153
-rw-r--r--Source/WebKit2/UIProcess/Launcher/mac/EnvironmentVariables.h68
-rw-r--r--Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm234
-rw-r--r--Source/WebKit2/UIProcess/Launcher/mac/ThreadLauncherMac.mm74
-rw-r--r--Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp196
-rw-r--r--Source/WebKit2/UIProcess/Launcher/qt/ThreadLauncherQt.cpp77
-rw-r--r--Source/WebKit2/UIProcess/Launcher/win/ProcessLauncherWin.cpp125
-rw-r--r--Source/WebKit2/UIProcess/Launcher/win/ThreadLauncherWin.cpp71
16 files changed, 1788 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp
new file mode 100644
index 000000000..e53d4156b
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * 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 "config.h"
+#include "ProcessLauncher.h"
+
+#include "WorkQueue.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebKit {
+
+static WorkQueue& processLauncherWorkQueue()
+{
+ DEFINE_STATIC_LOCAL(WorkQueue, processLauncherWorkQueue, ("com.apple.WebKit.ProcessLauncher"));
+ return processLauncherWorkQueue;
+}
+
+ProcessLauncher::ProcessLauncher(Client* client, const LaunchOptions& launchOptions)
+ : m_client(client)
+ , m_launchOptions(launchOptions)
+ , m_processIdentifier(0)
+{
+ // Launch the process.
+ m_isLaunching = true;
+ processLauncherWorkQueue().dispatch(bind(&ProcessLauncher::launchProcess, this));
+}
+
+void ProcessLauncher::didFinishLaunchingProcess(PlatformProcessIdentifier processIdentifier, CoreIPC::Connection::Identifier identifier)
+{
+ m_processIdentifier = processIdentifier;
+ m_isLaunching = false;
+
+ if (!m_client) {
+ // FIXME: Dispose of the connection identifier.
+ return;
+ }
+
+ m_client->didFinishLaunching(this, identifier);
+}
+
+void ProcessLauncher::invalidate()
+{
+ m_client = 0;
+ platformInvalidate();
+}
+
+const char* ProcessLauncher::processTypeAsString(ProcessType processType)
+{
+ switch (processType) {
+ case WebProcess:
+ return "webprocess";
+ case PluginProcess:
+ return "pluginprocess";
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+bool ProcessLauncher::getProcessTypeFromString(const char* string, ProcessType& processType)
+{
+ if (!strcmp(string, "webprocess")) {
+ processType = WebProcess;
+ return true;
+ }
+
+ if (!strcmp(string, "pluginprocess")) {
+ processType = PluginProcess;
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h
new file mode 100644
index 000000000..8dbfb1101
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * 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 WebProcessLauncher_h
+#define WebProcessLauncher_h
+
+#include "Connection.h"
+#include "PlatformProcessIdentifier.h"
+#include <wtf/RefPtr.h>
+#include <wtf/Threading.h>
+
+#if PLATFORM(QT)
+class QLocalSocket;
+#endif
+
+namespace WebKit {
+
+class ProcessLauncher : public ThreadSafeRefCounted<ProcessLauncher> {
+public:
+ class Client {
+ public:
+ virtual ~Client() { }
+
+ virtual void didFinishLaunching(ProcessLauncher*, CoreIPC::Connection::Identifier) = 0;
+ };
+
+ enum ProcessType {
+ WebProcess,
+ PluginProcess
+ };
+
+ struct LaunchOptions {
+ ProcessType processType;
+#if PLATFORM(MAC)
+ static const cpu_type_t MatchCurrentArchitecture = 0;
+ cpu_type_t architecture;
+ bool executableHeap;
+#endif
+ };
+
+ static PassRefPtr<ProcessLauncher> create(Client* client, const LaunchOptions& launchOptions)
+ {
+ return adoptRef(new ProcessLauncher(client, launchOptions));
+ }
+
+ bool isLaunching() const { return m_isLaunching; }
+ PlatformProcessIdentifier processIdentifier() const { return m_processIdentifier; }
+
+ void terminateProcess();
+ void invalidate();
+
+ static bool getProcessTypeFromString(const char*, ProcessType&);
+
+private:
+ ProcessLauncher(Client*, const LaunchOptions& launchOptions);
+
+ static const char* processTypeAsString(ProcessType);
+
+ void launchProcess();
+ void didFinishLaunchingProcess(PlatformProcessIdentifier, CoreIPC::Connection::Identifier);
+
+ void platformInvalidate();
+
+ Client* m_client;
+
+ const LaunchOptions m_launchOptions;
+ bool m_isLaunching;
+ PlatformProcessIdentifier m_processIdentifier;
+};
+
+} // namespace WebKit
+
+#endif // WebProcessLauncher_h
diff --git a/Source/WebKit2/UIProcess/Launcher/ThreadLauncher.cpp b/Source/WebKit2/UIProcess/Launcher/ThreadLauncher.cpp
new file mode 100644
index 000000000..3c0fbf160
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/ThreadLauncher.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * 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 "config.h"
+#include "ThreadLauncher.h"
+
+#include "RunLoop.h"
+
+namespace WebKit {
+
+ThreadLauncher::ThreadLauncher(Client* client)
+ : m_client(client)
+{
+ launchThread();
+}
+
+void ThreadLauncher::launchThread()
+{
+ m_isLaunching = true;
+
+ CoreIPC::Connection::Identifier connectionIdentifier = createWebThread();
+
+ // We've finished launching the thread, message back to the main run loop.
+ RunLoop::main()->dispatch(bind(&ThreadLauncher::didFinishLaunchingThread, this, connectionIdentifier));
+}
+
+void ThreadLauncher::didFinishLaunchingThread(CoreIPC::Connection::Identifier identifier)
+{
+ m_isLaunching = false;
+
+ if (!m_client) {
+ // FIXME: Dispose of the connection identifier.
+ return;
+ }
+
+ m_client->didFinishLaunching(this, identifier);
+}
+
+void ThreadLauncher::invalidate()
+{
+ m_client = 0;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/ThreadLauncher.h b/Source/WebKit2/UIProcess/Launcher/ThreadLauncher.h
new file mode 100644
index 000000000..f3a5312a2
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/ThreadLauncher.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * 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 ThreadLauncher_h
+#define ThreadLauncher_h
+
+#include "Connection.h"
+#include "PlatformProcessIdentifier.h"
+#include <wtf/RefPtr.h>
+#include <wtf/Threading.h>
+
+#if PLATFORM(QT)
+class QLocalSocket;
+#endif
+
+namespace WebKit {
+
+class ThreadLauncher : public ThreadSafeRefCounted<ThreadLauncher> {
+public:
+ class Client {
+ public:
+ virtual ~Client() { }
+ virtual void didFinishLaunching(ThreadLauncher*, CoreIPC::Connection::Identifier) = 0;
+ };
+
+ static PassRefPtr<ThreadLauncher> create(Client* client)
+ {
+ return adoptRef(new ThreadLauncher(client));
+ }
+
+ bool isLaunching() const { return m_isLaunching; }
+
+ void invalidate();
+
+private:
+ explicit ThreadLauncher(Client*);
+
+ void launchThread();
+ void didFinishLaunchingThread(CoreIPC::Connection::Identifier);
+
+ static CoreIPC::Connection::Identifier createWebThread();
+
+ bool m_isLaunching;
+ Client* m_client;
+};
+
+} // namespace WebKit
+
+#endif // ThreadLauncher_h
diff --git a/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp b/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp
new file mode 100644
index 000000000..d7a50829d
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
+ *
+ * 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 MOTOROLA 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 MOTOROLA 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 "config.h"
+#include "ProcessLauncher.h"
+
+#include "Connection.h"
+#include "RunLoop.h"
+#include <WebCore/FileSystem.h>
+#include <WebCore/ResourceHandle.h>
+#include <errno.h>
+#if OS(LINUX)
+#include <sys/prctl.h>
+#endif
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/gobject/GlibUtilities.h>
+
+#ifdef SOCK_SEQPACKET
+#define SOCKET_TYPE SOCK_SEQPACKET
+#else
+#define SOCKET_TYPE SOCK_STREAM
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+const char* gWebKitWebProcessName = "WebKitWebProcess";
+const char* gWebKitPluginProcessName = "WebKitPluginProcess";
+
+static void childSetupFunction(gpointer userData)
+{
+ int socket = GPOINTER_TO_INT(userData);
+ close(socket);
+
+#if OS(LINUX)
+ // Kill child process when parent dies.
+ prctl(PR_SET_PDEATHSIG, SIGKILL);
+#endif
+}
+
+static void childFinishedFunction(GPid, gint status, gpointer userData)
+{
+ if (WIFEXITED(status) && !WEXITSTATUS(status))
+ return;
+
+ close(GPOINTER_TO_INT(userData));
+}
+
+static CString findWebKitProcess(const char* processName)
+{
+ const char* execDirectory = g_getenv("WEBKIT_EXEC_PATH");
+ if (execDirectory) {
+ String processPath = pathByAppendingComponent(filenameToString(execDirectory), processName);
+ if (fileExists(processPath))
+ return fileSystemRepresentation(processPath);
+ }
+
+ static bool gotExecutablePath = false;
+ static String executablePath;
+ if (!gotExecutablePath) {
+ gotExecutablePath = true;
+
+ CString executableFile = getCurrentExecutablePath();
+ if (!executableFile.isNull())
+ executablePath = directoryName(filenameToString(executableFile.data()));
+ }
+
+ if (!executablePath.isNull()) {
+ String processPath = pathByAppendingComponent(executablePath, processName);
+ if (fileExists(processPath))
+ return fileSystemRepresentation(processPath);
+ }
+
+ return fileSystemRepresentation(pathByAppendingComponent(filenameToString(LIBEXECDIR), processName));
+}
+
+void ProcessLauncher::launchProcess()
+{
+ GPid pid = 0;
+
+ int sockets[2];
+ if (socketpair(AF_UNIX, SOCKET_TYPE, 0, sockets) < 0) {
+ g_printerr("Creation of socket failed: %s.\n", g_strerror(errno));
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ CString binaryPath = findWebKitProcess(m_launchOptions.processType == ProcessLauncher::WebProcess ? gWebKitWebProcessName : gWebKitPluginProcessName);
+ GOwnPtr<gchar> socket(g_strdup_printf("%d", sockets[0]));
+ char* argv[3];
+ argv[0] = const_cast<char*>(binaryPath.data());
+ argv[1] = socket.get();
+ argv[2] = 0;
+
+ GOwnPtr<GError> error;
+ int spawnFlags = G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD;
+ if (!g_spawn_async(0, argv, 0, static_cast<GSpawnFlags>(spawnFlags), childSetupFunction, GINT_TO_POINTER(sockets[1]), &pid, &error.outPtr())) {
+ g_printerr("Unable to fork a new WebProcess: %s.\n", error->message);
+ ASSERT_NOT_REACHED();
+ }
+
+ close(sockets[0]);
+ m_processIdentifier = pid;
+
+ // Monitor the child process, it calls waitpid to prevent the child process from becomming a zombie,
+ // and it allows us to close the socket when the child process crashes.
+ g_child_watch_add(m_processIdentifier, childFinishedFunction, GINT_TO_POINTER(sockets[1]));
+
+ // We've finished launching the process, message back to the main run loop.
+ RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, m_processIdentifier, sockets[1]));
+}
+
+void ProcessLauncher::terminateProcess()
+{
+ if (!m_processIdentifier)
+ return;
+
+ kill(m_processIdentifier, SIGKILL);
+}
+
+void ProcessLauncher::platformInvalidate()
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/gtk/ThreadLauncherGtk.cpp b/Source/WebKit2/UIProcess/Launcher/gtk/ThreadLauncherGtk.cpp
new file mode 100644
index 000000000..84f72b54d
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/gtk/ThreadLauncherGtk.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
+ *
+ * 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 "config.h"
+#include "ThreadLauncher.h"
+
+#include <WebCore/NotImplemented.h>
+
+namespace WebKit {
+
+CoreIPC::Connection::Identifier ThreadLauncher::createWebThread()
+{
+ notImplemented();
+ return -1;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.h b/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.h
new file mode 100644
index 000000000..311e59087
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * 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 DynamicLinkerEnvironmentExtractor_h
+#define DynamicLinkerEnvironmentExtractor_h
+
+#ifndef BUILDING_ON_SNOW_LEOPARD
+
+#include <mach/machine.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
+
+namespace WebKit {
+
+class EnvironmentVariables;
+
+class DynamicLinkerEnvironmentExtractor {
+ WTF_MAKE_NONCOPYABLE(DynamicLinkerEnvironmentExtractor);
+
+public:
+ DynamicLinkerEnvironmentExtractor(NSString *executablePath, cpu_type_t architecture);
+
+ void getExtractedEnvironmentVariables(EnvironmentVariables&) const;
+
+private:
+ void processSingleArchitecture(const void* data, size_t length);
+ void processFatFile(const void* data, size_t length);
+ void processLoadCommands(const void* data, size_t length, int32_t numberOfCommands, bool shouldByteSwap);
+ size_t processLoadCommand(const void* data, size_t length, bool shouldByteSwap);
+ void processEnvironmentVariable(const char* environmentString);
+
+ RetainPtr<NSString> m_executablePath;
+ cpu_type_t m_architecture;
+
+ Vector<std::pair<CString, CString> > m_extractedVariables;
+};
+
+} // namespace WebKit
+
+#endif // BUILDING_ON_SNOW_LEOPARD
+
+#endif // DynamicLinkerEnvironmentExtractor_h
diff --git a/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm b/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm
new file mode 100644
index 000000000..70dccc58a
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * 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 "config.h"
+#include "DynamicLinkerEnvironmentExtractor.h"
+
+#ifndef BUILDING_ON_SNOW_LEOPARD
+
+#include "EnvironmentVariables.h"
+#include <mach-o/loader.h>
+#include <mach-o/swap.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+DynamicLinkerEnvironmentExtractor::DynamicLinkerEnvironmentExtractor(NSString *executablePath, cpu_type_t architecture)
+ : m_executablePath(executablePath)
+ , m_architecture(architecture)
+{
+ NSData *mainExecutableData = [NSData dataWithContentsOfFile:m_executablePath.get() options:NSDataReadingMappedIfSafe error:0];
+ if (!mainExecutableData)
+ return;
+
+ const void* mainExecutableBytes = [mainExecutableData bytes];
+ size_t length = [mainExecutableData length];
+ if (length < sizeof(uint32_t))
+ return;
+
+ uint32_t magicValue = *static_cast<const uint32_t*>(mainExecutableBytes);
+ if (magicValue == FAT_MAGIC || magicValue == FAT_CIGAM) {
+ processFatFile(mainExecutableBytes, length);
+ return;
+ }
+
+ processSingleArchitecture(mainExecutableBytes, length);
+}
+
+#define DEFINE_BYTE_SWAPPER(type) inline type byteSwapIfNeeded(const type& data, bool shouldByteSwap) \
+{ \
+ type swapped = data; \
+ if (shouldByteSwap) \
+ swap_##type(&swapped, NX_UnknownByteOrder); \
+ return swapped; \
+}
+
+DEFINE_BYTE_SWAPPER(load_command)
+DEFINE_BYTE_SWAPPER(dylinker_command)
+DEFINE_BYTE_SWAPPER(mach_header)
+DEFINE_BYTE_SWAPPER(mach_header_64)
+
+#undef DEFINE_BYTE_SWAPPER
+
+void DynamicLinkerEnvironmentExtractor::processEnvironmentVariable(const char* environmentString)
+{
+ const char* equalsLocation = strchr(environmentString, '=');
+ if (!equalsLocation)
+ return;
+
+ size_t nameLength = equalsLocation - environmentString;
+ String name(environmentString, nameLength);
+
+ // LC_DYLD_ENVIRONMENT only respects DYLD_*_PATH variables.
+ if (!name.startsWith("DYLD_") || !name.endsWith("_PATH"))
+ return;
+
+ CString value(equalsLocation + 1);
+ m_extractedVariables.append(make_pair(name.latin1(), value));
+}
+
+size_t DynamicLinkerEnvironmentExtractor::processLoadCommand(const void* data, size_t length, bool shouldByteSwap)
+{
+ if (length < sizeof(load_command))
+ return 0;
+
+ const load_command* rawLoadCommand = static_cast<const load_command*>(data);
+ load_command loadCommand = byteSwapIfNeeded(*rawLoadCommand, shouldByteSwap);
+
+ if (length < loadCommand.cmdsize)
+ return 0;
+
+ if (loadCommand.cmd == LC_DYLD_ENVIRONMENT) {
+ if (length < sizeof(dylinker_command))
+ return 0;
+
+ dylinker_command environmentCommand = byteSwapIfNeeded(*reinterpret_cast<const dylinker_command*>(rawLoadCommand), shouldByteSwap);
+ if (loadCommand.cmdsize < environmentCommand.name.offset)
+ return 0;
+
+ size_t environmentStringLength = loadCommand.cmdsize - environmentCommand.name.offset;
+ Vector<char, 256> environmentString;
+ environmentString.reserveCapacity(environmentStringLength + 1);
+ environmentString.append(reinterpret_cast<const char*>(rawLoadCommand) + environmentCommand.name.offset, environmentStringLength);
+ environmentString.append(0);
+
+ processEnvironmentVariable(environmentString.data());
+ }
+
+ return loadCommand.cmdsize;
+}
+
+void DynamicLinkerEnvironmentExtractor::processLoadCommands(const void* data, size_t length, int32_t numberOfCommands, bool shouldByteSwap)
+{
+ const void* dataRemaining = data;
+ size_t lengthRemaining = length;
+ for (int i = 0; i < numberOfCommands; i++) {
+ size_t commandLength = processLoadCommand(dataRemaining, lengthRemaining, shouldByteSwap);
+ if (!commandLength || lengthRemaining < commandLength)
+ return;
+
+ dataRemaining = static_cast<const char*>(dataRemaining) + commandLength;
+ lengthRemaining -= commandLength;
+ }
+}
+
+void DynamicLinkerEnvironmentExtractor::processSingleArchitecture(const void* data, size_t length)
+{
+ if (length < sizeof(mach_header))
+ return;
+
+ const mach_header* header = static_cast<const mach_header*>(data);
+ if (header->magic == MH_MAGIC || header->magic == MH_CIGAM) {
+ bool shouldByteSwap = header->magic == MH_CIGAM;
+ mach_header swappedHeader = byteSwapIfNeeded(*header, shouldByteSwap);
+ if (swappedHeader.cputype == m_architecture)
+ processLoadCommands(static_cast<const char*>(data) + sizeof(*header), length - sizeof(*header), swappedHeader.ncmds, shouldByteSwap);
+ return;
+ }
+
+ if (length < sizeof(mach_header_64))
+ return;
+
+ const mach_header_64* header64 = static_cast<const mach_header_64*>(data);
+ bool shouldByteSwap = header->magic == MH_CIGAM_64;
+ mach_header_64 swappedHeader64 = byteSwapIfNeeded(*header64, shouldByteSwap);
+ if (swappedHeader64.cputype == m_architecture)
+ processLoadCommands(static_cast<const char*>(data) + sizeof(*header64), length - sizeof(*header64), swappedHeader64.ncmds, shouldByteSwap);
+}
+
+void DynamicLinkerEnvironmentExtractor::processFatFile(const void* data, size_t length)
+{
+ if (length < sizeof(fat_header))
+ return;
+
+ const fat_header* header = static_cast<const fat_header*>(data);
+
+ size_t numberOfArchitectures = OSSwapBigToHostInt32(header->nfat_arch);
+
+ // Ensure that we have enough data remaining for numberOfArchitectures fat_arch structs.
+ if ((length - sizeof(fat_header)) / sizeof(fat_arch) < numberOfArchitectures)
+ return;
+
+ const fat_arch* archs = reinterpret_cast<const fat_arch*>(reinterpret_cast<const char*>(data) + sizeof(*header));
+ for (uint32_t i = 0; i < numberOfArchitectures; i++) {
+ uint32_t architectureOffset = OSSwapBigToHostInt32(archs[i].offset);
+ uint32_t architectureSize = OSSwapBigToHostInt32(archs[i].size);
+ if (length < architectureOffset + architectureSize)
+ return;
+
+ processSingleArchitecture(static_cast<const char*>(data) + architectureOffset, architectureSize);
+ }
+}
+
+void DynamicLinkerEnvironmentExtractor::getExtractedEnvironmentVariables(EnvironmentVariables& environmentVariables) const
+{
+ size_t extractedVariableCount = m_extractedVariables.size();
+ for (size_t i = 0; i < extractedVariableCount; ++i) {
+ const CString& name = m_extractedVariables[i].first;
+
+ // Preserve any existing environment variable by this name so that it will take
+ // precedence over what we extracted from the executable file.
+ if (environmentVariables.get(name.data()))
+ continue;
+
+ environmentVariables.set(name.data(), m_extractedVariables[i].second.data());
+ }
+}
+
+} // namespace WebKit
+
+#endif // BUILDING_ON_SNOW_LEOPARD
diff --git a/Source/WebKit2/UIProcess/Launcher/mac/EnvironmentVariables.cpp b/Source/WebKit2/UIProcess/Launcher/mac/EnvironmentVariables.cpp
new file mode 100644
index 000000000..72979f8f7
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/mac/EnvironmentVariables.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ *
+ * 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 "config.h"
+#include "EnvironmentVariables.h"
+
+#include <crt_externs.h>
+
+namespace WebKit {
+
+EnvironmentVariables::EnvironmentVariables()
+ : m_environmentPointer(*_NSGetEnviron())
+{
+}
+
+EnvironmentVariables::~EnvironmentVariables()
+{
+ size_t size = m_allocatedStrings.size();
+ for (size_t i = 0; i < size; ++i)
+ fastFree(m_allocatedStrings[i]);
+}
+
+void EnvironmentVariables::set(const char* name, const char* value)
+{
+ // Check if we need to copy the environment.
+ if (m_environmentPointer == *_NSGetEnviron())
+ copyEnvironmentVariables();
+
+ // Allocate a string for the name and value.
+ const char* nameAndValue = createStringForVariable(name, value);
+
+ for (size_t i = 0; i < m_environmentVariables.size() - 1; ++i) {
+ if (valueIfVariableHasName(m_environmentVariables[i], name)) {
+ // Just replace the environment variable.
+ m_environmentVariables[i] = const_cast<char*>(nameAndValue);
+ return;
+ }
+ }
+
+ // Append the new string.
+ ASSERT(!m_environmentVariables.last());
+ m_environmentVariables.last() = const_cast<char*>(nameAndValue);
+ m_environmentVariables.append(static_cast<char*>(0));
+
+ m_environmentPointer = m_environmentVariables.data();
+}
+
+const char* EnvironmentVariables::get(const char* name) const
+{
+ for (size_t i = 0; m_environmentPointer[i]; ++i) {
+ if (const char* value = valueIfVariableHasName(m_environmentPointer[i], name))
+ return value;
+ }
+ return 0;
+}
+
+void EnvironmentVariables::appendValue(const char* name, const char* value, char separator)
+{
+ const char* existingValue = get(name);
+ if (!existingValue) {
+ set(name, value);
+ return;
+ }
+
+ Vector<char, 128> newValue;
+ newValue.append(existingValue, strlen(existingValue));
+ newValue.append(separator);
+ newValue.append(value, strlen(value) + 1);
+
+ set(name, newValue.data());
+}
+
+const char* EnvironmentVariables::valueIfVariableHasName(const char* environmentVariable, const char* name) const
+{
+ // Find the environment variable name.
+ const char* equalsLocation = strchr(environmentVariable, '=');
+ ASSERT(equalsLocation);
+
+ size_t nameLength = equalsLocation - environmentVariable;
+ if (strlen(name) != nameLength)
+ return 0;
+ if (memcmp(environmentVariable, name, nameLength))
+ return 0;
+
+ return equalsLocation + 1;
+}
+
+const char* EnvironmentVariables::createStringForVariable(const char* name, const char* value)
+{
+ int nameLength = strlen(name);
+ int valueLength = strlen(value);
+
+ // Allocate enough room to hold 'name=value' and the null character.
+ char* string = static_cast<char*>(fastMalloc(nameLength + 1 + valueLength + 1));
+ memcpy(string, name, nameLength);
+ string[nameLength] = '=';
+ memcpy(string + nameLength + 1, value, valueLength);
+ string[nameLength + 1 + valueLength] = '\0';
+
+ m_allocatedStrings.append(string);
+
+ return string;
+}
+
+void EnvironmentVariables::copyEnvironmentVariables()
+{
+ for (size_t i = 0; (*_NSGetEnviron())[i]; i++)
+ m_environmentVariables.append((*_NSGetEnviron())[i]);
+
+ // Null-terminate the array.
+ m_environmentVariables.append(static_cast<char*>(0));
+
+ // Update the environment pointer.
+ m_environmentPointer = m_environmentVariables.data();
+}
+
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+
+const char* EnvironmentVariables::preexistingProcessServiceNameKey()
+{
+ return "WEBKIT_PREEXISTING_PROCESS_SERVICE_NAME";
+}
+
+const char* EnvironmentVariables::preexistingProcessTypeKey()
+{
+ return "WEBKIT_PREEXISTING_PROCESS_TYPE";
+}
+
+#endif // !defined(BUILDING_ON_SNOW_LEOPARD)
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/mac/EnvironmentVariables.h b/Source/WebKit2/UIProcess/Launcher/mac/EnvironmentVariables.h
new file mode 100644
index 000000000..33829398d
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/mac/EnvironmentVariables.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ *
+ * 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 EnvironmentVariables_h
+#define EnvironmentVariables_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebKit {
+
+class EnvironmentVariables {
+ WTF_MAKE_NONCOPYABLE(EnvironmentVariables);
+
+public:
+ EnvironmentVariables();
+ ~EnvironmentVariables();
+
+ void set(const char* name, const char* value);
+ const char* get(const char* name) const;
+
+ // Will append the value with the given separator if the environment variable already exists.
+ void appendValue(const char* name, const char* value, char separator);
+
+ char** environmentPointer() const { return m_environmentPointer; }
+
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ static const char* preexistingProcessServiceNameKey();
+ static const char* preexistingProcessTypeKey();
+#endif
+
+private:
+ const char* valueIfVariableHasName(const char* environmentVariable, const char* name) const;
+ const char* createStringForVariable(const char* name, const char* value);
+ void copyEnvironmentVariables();
+
+ char** m_environmentPointer;
+ Vector<char*> m_environmentVariables;
+
+ // These allocated strings will be freed in the destructor.
+ Vector<char*> m_allocatedStrings;
+};
+
+} // namespace WebKit
+
+#endif // EnvironmentVariables_h
diff --git a/Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm b/Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm
new file mode 100644
index 000000000..c70f62edf
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#import "config.h"
+#import "ProcessLauncher.h"
+
+#import "DynamicLinkerEnvironmentExtractor.h"
+#import "EnvironmentVariables.h"
+#import "RunLoop.h"
+#import "WebProcess.h"
+#import "WebKitSystemInterface.h"
+#import <crt_externs.h>
+#import <mach-o/dyld.h>
+#import <mach/machine.h>
+#import <runtime/InitializeThreading.h>
+#import <servers/bootstrap.h>
+#import <spawn.h>
+#import <sys/param.h>
+#import <sys/stat.h>
+#import <wtf/PassRefPtr.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/Threading.h>
+#import <wtf/text/CString.h>
+#import <wtf/text/WTFString.h>
+
+using namespace WebCore;
+
+// FIXME: We should be doing this another way.
+extern "C" kern_return_t bootstrap_register2(mach_port_t, name_t, mach_port_t, uint64_t);
+
+namespace WebKit {
+
+static void setUpTerminationNotificationHandler(pid_t pid)
+{
+#if HAVE(DISPATCH_H)
+ dispatch_source_t processDiedSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, pid, DISPATCH_PROC_EXIT, dispatch_get_current_queue());
+ dispatch_source_set_event_handler(processDiedSource, ^{
+ int status;
+ waitpid(dispatch_source_get_handle(processDiedSource), &status, 0);
+ dispatch_source_cancel(processDiedSource);
+ });
+ dispatch_source_set_cancel_handler(processDiedSource, ^{
+ dispatch_release(processDiedSource);
+ });
+ dispatch_resume(processDiedSource);
+#endif
+}
+
+void ProcessLauncher::launchProcess()
+{
+ // Create the listening port.
+ mach_port_t listeningPort;
+ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
+
+ // Insert a send right so we can send to it.
+ mach_port_insert_right(mach_task_self(), listeningPort, listeningPort, MACH_MSG_TYPE_MAKE_SEND);
+
+ pid_t processIdentifier = 0;
+
+ EnvironmentVariables environmentVariables;
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ static const char* preexistingProcessServiceName = environmentVariables.get(EnvironmentVariables::preexistingProcessServiceNameKey());
+ ProcessType preexistingProcessType;
+ if (preexistingProcessServiceName)
+ getProcessTypeFromString(environmentVariables.get(EnvironmentVariables::preexistingProcessTypeKey()), preexistingProcessType);
+
+ bool usePreexistingProcess = preexistingProcessServiceName && preexistingProcessType == m_launchOptions.processType;
+
+ if (usePreexistingProcess) {
+ mach_port_t lookupPort;
+ bootstrap_look_up(bootstrap_port, preexistingProcessServiceName, &lookupPort);
+
+ mach_msg_header_t header;
+ header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND);
+ header.msgh_id = 0;
+ header.msgh_local_port = listeningPort;
+ header.msgh_remote_port = lookupPort;
+ header.msgh_size = sizeof(header);
+ kern_return_t kr = mach_msg(&header, MACH_SEND_MSG, sizeof(header), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+ if (kr) {
+ LOG_ERROR("Failed to pick up preexisting process at %s (%x). Launching a new process of type %s instead.", preexistingProcessServiceName, kr, processTypeAsString(m_launchOptions.processType));
+ usePreexistingProcess = false;
+ }
+
+ mach_port_deallocate(mach_task_self(), lookupPort);
+
+ preexistingProcessServiceName = 0;
+ }
+
+ if (!usePreexistingProcess) {
+#endif
+ NSBundle *webKit2Bundle = [NSBundle bundleWithIdentifier:@"com.apple.WebKit2"];
+ NSString *frameworksPath = [[webKit2Bundle bundlePath] stringByDeletingLastPathComponent];
+ const char* frameworkExecutablePath = [[webKit2Bundle executablePath] fileSystemRepresentation];
+
+ NSString *processPath;
+ if (m_launchOptions.processType == ProcessLauncher::PluginProcess)
+ processPath = [webKit2Bundle pathForAuxiliaryExecutable:@"PluginProcess.app"];
+ else
+ processPath = [webKit2Bundle pathForAuxiliaryExecutable:@"WebProcess.app"];
+
+ NSString *processAppExecutablePath = [[NSBundle bundleWithPath:processPath] executablePath];
+
+ RetainPtr<CFStringRef> cfLocalization(AdoptCF, WKCopyCFLocalizationPreferredName(NULL));
+ CString localization = String(cfLocalization.get()).utf8();
+
+ // Make a unique, per pid, per process launcher web process service name.
+ CString serviceName = String::format("com.apple.WebKit.WebProcess-%d-%p", getpid(), this).utf8();
+
+ const char* args[] = { [processAppExecutablePath fileSystemRepresentation], frameworkExecutablePath, "-type", processTypeAsString(m_launchOptions.processType), "-servicename", serviceName.data(), "-localization", localization.data(), 0 };
+
+ // Register ourselves.
+ kern_return_t kr = bootstrap_register2(bootstrap_port, const_cast<char*>(serviceName.data()), listeningPort, 0);
+ ASSERT_UNUSED(kr, kr == KERN_SUCCESS);
+
+ posix_spawnattr_t attr;
+ posix_spawnattr_init(&attr);
+
+ short flags = 0;
+
+ // We want our process to receive all signals.
+ sigset_t signalMaskSet;
+ sigemptyset(&signalMaskSet);
+
+ posix_spawnattr_setsigmask(&attr, &signalMaskSet);
+ flags |= POSIX_SPAWN_SETSIGMASK;
+
+ // Determine the architecture to use.
+ cpu_type_t architecture = m_launchOptions.architecture;
+ if (architecture == LaunchOptions::MatchCurrentArchitecture)
+ architecture = _NSGetMachExecuteHeader()->cputype;
+
+ cpu_type_t cpuTypes[] = { architecture };
+ size_t outCount = 0;
+ posix_spawnattr_setbinpref_np(&attr, 1, cpuTypes, &outCount);
+
+ // Start suspended so we can set up the termination notification handler.
+ flags |= POSIX_SPAWN_START_SUSPENDED;
+
+#ifndef BUILDING_ON_SNOW_LEOPARD
+ static const int allowExecutableHeapFlag = 0x2000;
+ if (m_launchOptions.executableHeap)
+ flags |= allowExecutableHeapFlag;
+#endif
+
+ posix_spawnattr_setflags(&attr, flags);
+
+#ifndef BUILDING_ON_SNOW_LEOPARD
+ DynamicLinkerEnvironmentExtractor environmentExtractor([[NSBundle mainBundle] executablePath], architecture);
+ environmentExtractor.getExtractedEnvironmentVariables(environmentVariables);
+#endif
+
+ // To make engineering builds work, if the path is outside of /System set up
+ // DYLD_FRAMEWORK_PATH to pick up other frameworks, but don't do it for the
+ // production configuration because it involves extra file system access.
+ if (![frameworksPath hasPrefix:@"/System/"])
+ environmentVariables.appendValue("DYLD_FRAMEWORK_PATH", [frameworksPath fileSystemRepresentation], ':');
+
+ NSString *processShimPathNSString = nil;
+ if (m_launchOptions.processType == ProcessLauncher::PluginProcess)
+ processShimPathNSString = [[processAppExecutablePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"PluginProcessShim.dylib"];
+ else if (m_launchOptions.processType == ProcessLauncher::WebProcess)
+ processShimPathNSString = [[processAppExecutablePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"WebProcessShim.dylib"];
+
+ // Make sure that the shim library file exists and insert it.
+ if (processShimPathNSString) {
+ const char* processShimPath = [processShimPathNSString fileSystemRepresentation];
+ struct stat statBuf;
+ if (stat(processShimPath, &statBuf) == 0 && (statBuf.st_mode & S_IFMT) == S_IFREG)
+ environmentVariables.appendValue("DYLD_INSERT_LIBRARIES", processShimPath, ':');
+ }
+
+ int result = posix_spawn(&processIdentifier, args[0], 0, &attr, const_cast<char**>(args), environmentVariables.environmentPointer());
+
+ posix_spawnattr_destroy(&attr);
+
+ if (!result) {
+ // Set up the termination notification handler and then ask the child process to continue.
+ setUpTerminationNotificationHandler(processIdentifier);
+ kill(processIdentifier, SIGCONT);
+ } else {
+ // We failed to launch. Release the send right.
+ mach_port_deallocate(mach_task_self(), listeningPort);
+
+ // And the receive right.
+ mach_port_mod_refs(mach_task_self(), listeningPort, MACH_PORT_RIGHT_RECEIVE, -1);
+
+ listeningPort = MACH_PORT_NULL;
+ processIdentifier = 0;
+ }
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ }
+#endif
+
+ // We've finished launching the process, message back to the main run loop.
+ RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, processIdentifier, listeningPort));
+}
+
+void ProcessLauncher::terminateProcess()
+{
+ if (!m_processIdentifier)
+ return;
+
+ kill(m_processIdentifier, SIGKILL);
+}
+
+void ProcessLauncher::platformInvalidate()
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/mac/ThreadLauncherMac.mm b/Source/WebKit2/UIProcess/Launcher/mac/ThreadLauncherMac.mm
new file mode 100644
index 000000000..1c74b7d28
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/mac/ThreadLauncherMac.mm
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#import "config.h"
+#import "ThreadLauncher.h"
+
+#import "RunLoop.h"
+#import "WebProcess.h"
+#import "WebSystemInterface.h"
+#import <runtime/InitializeThreading.h>
+#import <wtf/MainThread.h>
+#import <wtf/Threading.h>
+
+namespace WebKit {
+
+static void* webThreadBody(void* context)
+{
+ mach_port_t serverPort = static_cast<mach_port_t>(reinterpret_cast<uintptr_t>(context));
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ InitWebCoreSystemInterface();
+ JSC::initializeThreading();
+ WTF::initializeMainThread();
+
+ WebProcess::shared().initialize(serverPort, RunLoop::current());
+
+ [pool drain];
+
+ RunLoop::current()->run();
+
+ return 0;
+}
+
+CoreIPC::Connection::Identifier ThreadLauncher::createWebThread()
+{
+ // Create the service port.
+ mach_port_t listeningPort;
+ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
+
+ // Insert a send right so we can send to it.
+ mach_port_insert_right(mach_task_self(), listeningPort, listeningPort, MACH_MSG_TYPE_MAKE_SEND);
+
+ if (!createThread(webThreadBody, reinterpret_cast<void*>(listeningPort), "WebKit2: WebThread")) {
+ mach_port_destroy(mach_task_self(), listeningPort);
+ return MACH_PORT_NULL;
+ }
+
+ return listeningPort;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp b/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp
new file mode 100644
index 000000000..837f59baf
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 "config.h"
+#include "ProcessLauncher.h"
+
+#include "Connection.h"
+#include "RunLoop.h"
+#include "WebProcess.h"
+#include <QCoreApplication>
+#include <QDebug>
+#include <QFile>
+#include <QLocalServer>
+#include <QMetaType>
+#include <QProcess>
+#include <QString>
+#include <QtCore/qglobal.h>
+#include <WebCore/NotImplemented.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <runtime/InitializeThreading.h>
+#include <string>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <wtf/HashSet.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+#include <wtf/text/WTFString.h>
+#if defined(Q_OS_LINUX)
+#include <sys/prctl.h>
+#include <signal.h>
+#endif
+
+#if OS(DARWIN)
+#include <mach/mach_init.h>
+#include <servers/bootstrap.h>
+
+extern "C" kern_return_t bootstrap_register2(mach_port_t, name_t, mach_port_t, uint64_t);
+#endif
+
+#if defined(SOCK_SEQPACKET) && !defined(Q_OS_MACX)
+#define SOCKET_TYPE SOCK_SEQPACKET
+#else
+#define SOCKET_TYPE SOCK_DGRAM
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+class QtWebProcess : public QProcess
+{
+ Q_OBJECT
+public:
+ QtWebProcess(QObject* parent = 0)
+ : QProcess(parent)
+ {
+ }
+
+protected:
+ virtual void setupChildProcess();
+};
+
+void QtWebProcess::setupChildProcess()
+{
+#if defined(Q_OS_LINUX)
+#ifndef NDEBUG
+ if (qgetenv("QT_WEBKIT2_DEBUG") == "1")
+ return;
+#endif
+ prctl(PR_SET_PDEATHSIG, SIGKILL);
+#endif
+#if defined(Q_OS_MACX)
+ qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", QByteArray("1"));
+#endif
+}
+
+void ProcessLauncher::launchProcess()
+{
+ QString applicationPath = QLatin1String("%1 %2");
+
+ if (QFile::exists(QCoreApplication::applicationDirPath() + QLatin1String("/QtWebProcess"))) {
+ applicationPath = applicationPath.arg(QCoreApplication::applicationDirPath() + QLatin1String("/QtWebProcess"));
+ } else {
+ applicationPath = applicationPath.arg(QLatin1String("QtWebProcess"));
+ }
+
+#if OS(DARWIN)
+ // Create the listening port.
+ mach_port_t connector;
+ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &connector);
+
+ // Insert a send right so we can send to it.
+ mach_port_insert_right(mach_task_self(), connector, connector, MACH_MSG_TYPE_MAKE_SEND);
+
+ // Register port with a service name to the system.
+ QString serviceName = QString("com.nokia.Qt.WebKit.QtWebProcess-%1-%2");
+ serviceName = serviceName.arg(QString().setNum(getpid()), QString().setNum((size_t)this));
+ kern_return_t kr = bootstrap_register2(bootstrap_port, const_cast<char*>(serviceName.toUtf8().data()), connector, 0);
+ ASSERT_UNUSED(kr, kr == KERN_SUCCESS);
+
+ QString program(applicationPath.arg(serviceName));
+#else
+ int sockets[2];
+ if (socketpair(AF_UNIX, SOCKET_TYPE, 0, sockets) == -1) {
+ qDebug() << "Creation of socket failed with errno:" << errno;
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ // Don't expose the ui socket to the web process
+ while (fcntl(sockets[1], F_SETFD, FD_CLOEXEC) == -1) {
+ if (errno != EINTR) {
+ ASSERT_NOT_REACHED();
+ while (close(sockets[0]) == -1 && errno == EINTR) { }
+ while (close(sockets[1]) == -1 && errno == EINTR) { }
+ return;
+ }
+ }
+
+ int connector = sockets[1];
+ QString program(applicationPath.arg(sockets[0]));
+#endif
+
+ QProcess* webProcess = new QtWebProcess();
+ webProcess->setProcessChannelMode(QProcess::ForwardedChannels);
+ webProcess->start(program);
+
+#if !OS(DARWIN)
+ // Don't expose the web socket to possible future web processes
+ while (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1) {
+ if (errno != EINTR) {
+ ASSERT_NOT_REACHED();
+ delete webProcess;
+ return;
+ }
+ }
+#endif
+
+ if (!webProcess->waitForStarted()) {
+ qDebug() << "Failed to start" << program;
+ ASSERT_NOT_REACHED();
+#if OS(DARWIN)
+ mach_port_deallocate(mach_task_self(), connector);
+ mach_port_mod_refs(mach_task_self(), connector, MACH_PORT_RIGHT_RECEIVE, -1);
+#endif
+ delete webProcess;
+ return;
+ }
+
+ setpriority(PRIO_PROCESS, webProcess->pid(), 10);
+
+ RunLoop::main()->dispatch(bind(&WebKit::ProcessLauncher::didFinishLaunchingProcess, this, webProcess, connector));
+}
+
+void ProcessLauncher::terminateProcess()
+{
+ if (!m_processIdentifier)
+ return;
+
+ QObject::connect(m_processIdentifier, SIGNAL(finished(int)), m_processIdentifier, SLOT(deleteLater()), Qt::QueuedConnection);
+ m_processIdentifier->terminate();
+}
+
+void ProcessLauncher::platformInvalidate()
+{
+
+}
+
+} // namespace WebKit
+
+#include "ProcessLauncherQt.moc"
diff --git a/Source/WebKit2/UIProcess/Launcher/qt/ThreadLauncherQt.cpp b/Source/WebKit2/UIProcess/Launcher/qt/ThreadLauncherQt.cpp
new file mode 100644
index 000000000..7b95ca049
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/qt/ThreadLauncherQt.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 "config.h"
+#include "ThreadLauncher.h"
+
+#include "RunLoop.h"
+#include "WebProcess.h"
+#include <runtime/InitializeThreading.h>
+#include <wtf/MainThread.h>
+#include <wtf/Threading.h>
+
+#include <QDebug>
+#include <QFile>
+#include <QLocalServer>
+#include <QProcess>
+
+#include <QtCore/qglobal.h>
+
+#include <sys/resource.h>
+#include <unistd.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static void* webThreadBody(void* /* context */)
+{
+ // Initialization
+ JSC::initializeThreading();
+ WTF::initializeMainThread();
+
+ // FIXME: We do not support threaded mode for now.
+
+ WebProcess::shared().initialize(-1, RunLoop::current());
+ RunLoop::run();
+
+ return 0;
+}
+
+CoreIPC::Connection::Identifier ThreadLauncher::createWebThread()
+{
+ srandom(time(0));
+ int connectionIdentifier = random();
+
+ if (!createThread(webThreadBody, reinterpret_cast<void*>(connectionIdentifier), "WebKit2: WebThread")) {
+ qWarning() << "failed starting thread";
+ return 0;
+ }
+
+ return connectionIdentifier;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/win/ProcessLauncherWin.cpp b/Source/WebKit2/UIProcess/Launcher/win/ProcessLauncherWin.cpp
new file mode 100644
index 000000000..d526c0307
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/win/ProcessLauncherWin.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * 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 "config.h"
+#include "ProcessLauncher.h"
+
+#include "Connection.h"
+#include "RunLoop.h"
+#include <shlwapi.h>
+#include <wtf/text/WTFString.h>
+
+#ifdef DEBUG_ALL
+const LPCWSTR webProcessName = L"WebKit2WebProcess_debug.exe";
+#else
+const LPCWSTR webProcessName = L"WebKit2WebProcess.exe";
+#endif
+
+#ifdef DEBUG_ALL
+const LPCWSTR webKitDLLName = L"WebKit_debug.dll";
+#else
+const LPCWSTR webKitDLLName = L"WebKit.dll";
+#endif
+
+namespace WebKit {
+
+void ProcessLauncher::launchProcess()
+{
+ // First, create the server and client identifiers.
+ HANDLE serverIdentifier, clientIdentifier;
+ if (!CoreIPC::Connection::createServerAndClientIdentifiers(serverIdentifier, clientIdentifier)) {
+ // FIXME: What should we do here?
+ ASSERT_NOT_REACHED();
+ }
+
+ // Ensure that the child process inherits the client identifier.
+ ::SetHandleInformation(clientIdentifier, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
+
+ // To get the full file path to WebKit2WebProcess.exe, we fild the location of WebKit.dll,
+ // remove the last path component, and then append WebKit2WebProcess(_debug).exe.
+ HMODULE webKitModule = ::GetModuleHandleW(webKitDLLName);
+ ASSERT(webKitModule);
+ if (!webKitModule)
+ return;
+
+ WCHAR pathStr[MAX_PATH];
+ if (!::GetModuleFileNameW(webKitModule, pathStr, WTF_ARRAY_LENGTH(pathStr)))
+ return;
+
+ ::PathRemoveFileSpecW(pathStr);
+ if (!::PathAppendW(pathStr, webProcessName))
+ return;
+
+ String commandLine(pathStr);
+
+ // FIXME: It would be nice if we could just create a CommandLine object and output a command line vector from it.
+ Vector<UChar> commandLineVector;
+ append(commandLineVector, "\"");
+ append(commandLineVector, commandLine);
+ append(commandLineVector, "\"");
+ append(commandLineVector, " -type webprocess");
+ append(commandLineVector, " -clientIdentifier ");
+ append(commandLineVector, String::number(reinterpret_cast<uintptr_t>(clientIdentifier)));
+ commandLineVector.append('\0');
+
+ STARTUPINFO startupInfo = { 0 };
+ startupInfo.cb = sizeof(startupInfo);
+ PROCESS_INFORMATION processInformation = { 0 };
+ BOOL result = ::CreateProcessW(0, commandLineVector.data(), 0, 0, true, 0, 0, 0, &startupInfo, &processInformation);
+
+ // We can now close the client identifier handle.
+ ::CloseHandle(clientIdentifier);
+
+ if (!result) {
+ // FIXME: What should we do here?
+ DWORD error = ::GetLastError();
+ ASSERT_NOT_REACHED();
+ }
+
+ // Don't leak the thread handle.
+ ::CloseHandle(processInformation.hThread);
+
+ // We've finished launching the process, message back to the run loop.
+ RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, processInformation.hProcess, serverIdentifier));
+}
+
+void ProcessLauncher::terminateProcess()
+{
+ if (!m_processIdentifier)
+ return;
+
+ ::TerminateProcess(m_processIdentifier, 0);
+}
+
+void ProcessLauncher::platformInvalidate()
+{
+ if (!m_processIdentifier)
+ return;
+
+ ::CloseHandle(m_processIdentifier);
+ m_processIdentifier = 0;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/win/ThreadLauncherWin.cpp b/Source/WebKit2/UIProcess/Launcher/win/ThreadLauncherWin.cpp
new file mode 100644
index 000000000..2596998ea
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/win/ThreadLauncherWin.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * 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 "config.h"
+#include "ThreadLauncher.h"
+
+#include "RunLoop.h"
+#include "WebProcess.h"
+#include <runtime/InitializeThreading.h>
+#include <wtf/MainThread.h>
+#include <wtf/Threading.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static void* webThreadBody(void* context)
+{
+ HANDLE clientIdentifier = reinterpret_cast<HANDLE>(context);
+
+ // Initialization
+ JSC::initializeThreading();
+ WTF::initializeMainThread();
+
+ WebProcess::shared().initialize(clientIdentifier, RunLoop::current());
+ RunLoop::run();
+
+ return 0;
+}
+
+CoreIPC::Connection::Identifier ThreadLauncher::createWebThread()
+{
+ // First, create the server and client identifiers.
+ HANDLE serverIdentifier, clientIdentifier;
+ if (!CoreIPC::Connection::createServerAndClientIdentifiers(serverIdentifier, clientIdentifier)) {
+ // FIXME: What should we do here?
+ ASSERT_NOT_REACHED();
+ }
+
+ if (!createThread(webThreadBody, reinterpret_cast<void*>(clientIdentifier), "WebKit2: WebThread")) {
+ ::CloseHandle(serverIdentifier);
+ ::CloseHandle(clientIdentifier);
+ return 0;
+ }
+
+ return serverIdentifier;
+}
+
+} // namespace WebKit