summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/UIProcess/Launcher
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/Launcher')
-rw-r--r--Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp96
-rw-r--r--Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h99
-rw-r--r--Source/WebKit2/UIProcess/Launcher/ThreadLauncher.cpp65
-rw-r--r--Source/WebKit2/UIProcess/Launcher/ThreadLauncher.h71
-rw-r--r--Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp86
-rw-r--r--Source/WebKit2/UIProcess/Launcher/gtk/ThreadLauncherGtk.cpp39
-rw-r--r--Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm311
-rw-r--r--Source/WebKit2/UIProcess/Launcher/mac/ThreadLauncherMac.mm72
-rw-r--r--Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp223
-rw-r--r--Source/WebKit2/UIProcess/Launcher/qt/ThreadLauncherQt.cpp77
-rw-r--r--Source/WebKit2/UIProcess/Launcher/win/ProcessLauncherWin.cpp122
-rw-r--r--Source/WebKit2/UIProcess/Launcher/win/ThreadLauncherWin.cpp69
12 files changed, 1330 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp
new file mode 100644
index 0000000..507edfa
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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 "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().scheduleWork(WorkItem::create(this, &ProcessLauncher::launchProcess));
+}
+
+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 0000000..31efd4d
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h
@@ -0,0 +1,99 @@
+/*
+ * 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 ThreadSafeShared<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;
+#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&);
+
+#if PLATFORM(QT)
+ friend class ProcessLauncherHelper;
+ static QLocalSocket* takePendingConnection();
+#endif
+
+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 0000000..69e4893
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/ThreadLauncher.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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 "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()->scheduleWork(WorkItem::create(this, &ThreadLauncher::didFinishLaunchingThread, 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 0000000..9c90fbd
--- /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 ThreadSafeShared<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 0000000..2565a48
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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 "ProcessLauncher.h"
+
+#include "Connection.h"
+#include "RunLoop.h"
+#include <WebCore/FileSystem.h>
+#include <WebCore/ResourceHandle.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+#include <wtf/gobject/GOwnPtr.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+const char* gWebKitWebProcessName = "WebKitWebProcess";
+
+void ProcessLauncher::launchProcess()
+{
+ pid_t pid = 0;
+
+ int sockets[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
+ fprintf(stderr, "Creation of socket failed with errno %d.\n", errno);
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ pid = fork();
+ if (!pid) { // child process
+ close(sockets[1]);
+ String socket = String::format("%d", sockets[0]);
+ GOwnPtr<gchar> binaryPath(g_build_filename(applicationDirectoryPath().data(), gWebKitWebProcessName, NULL));
+ execl(binaryPath.get(), gWebKitWebProcessName, socket.utf8().data(), NULL);
+ } else if (pid > 0) { // parent process
+ close(sockets[0]);
+ m_processIdentifier = pid;
+ // We've finished launching the process, message back to the main run loop.
+ RunLoop::main()->scheduleWork(WorkItem::create(this, &ProcessLauncher::didFinishLaunchingProcess, pid, sockets[1]));
+ } else {
+ fprintf(stderr, "Unable to fork a new WebProcess with errno: %d.\n", errno);
+ ASSERT_NOT_REACHED();
+ }
+}
+
+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 0000000..2841e0a
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/gtk/ThreadLauncherGtk.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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 "ThreadLauncher.h"
+
+#include "NotImplemented.h"
+
+namespace WebKit {
+
+CoreIPC::Connection::Identifier ThreadLauncher::createWebThread()
+{
+ notImplemented();
+ return -1;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm b/Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm
new file mode 100644
index 0000000..c285bae
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm
@@ -0,0 +1,311 @@
+/*
+ * 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 "ProcessLauncher.h"
+
+#include "RunLoop.h"
+#include "WebProcess.h"
+#include "WebKitSystemInterface.h"
+#include <crt_externs.h>
+#include <mach-o/dyld.h>
+#include <mach/machine.h>
+#include <runtime/InitializeThreading.h>
+#include <servers/bootstrap.h>
+#include <spawn.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Threading.h>
+#include <wtf/text/CString.h>
+#include <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 {
+
+#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+static const char* processName()
+{
+ return [[[NSProcessInfo processInfo] processName] fileSystemRepresentation];
+}
+#else
+// -[NSProcessInfo processName] isn't thread-safe on Leopard and Snow Leopard so we have our own implementation.
+static const char* createProcessName()
+{
+ uint32_t bufferSize = MAXPATHLEN;
+ char executablePath[bufferSize];
+
+ if (_NSGetExecutablePath(executablePath, &bufferSize))
+ return "";
+
+ const char *processName = strrchr(executablePath, '/') + 1;
+ return strdup(processName);
+}
+
+static const char* processName()
+{
+ static const char* processName = createProcessName();
+ return processName;
+}
+#endif
+
+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
+}
+
+class EnvironmentVariables {
+ WTF_MAKE_NONCOPYABLE(EnvironmentVariables);
+
+public:
+ EnvironmentVariables()
+ : m_environmentPointer(*_NSGetEnviron())
+ {
+ }
+
+ ~EnvironmentVariables()
+ {
+ deleteAllValues(m_allocatedStrings);
+ }
+
+ void 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.
+ char* nameAndValue = createStringForVariable(name, value);
+
+ for (size_t i = 0; i < m_environmentVariables.size() - 1; ++i) {
+ char* environmentVariable = m_environmentVariables[i];
+
+ if (valueIfVariableHasName(environmentVariable, name)) {
+ // Just replace the environment variable.
+ m_environmentVariables[i] = nameAndValue;
+ return;
+ }
+ }
+
+ // Append the new string.
+ ASSERT(!m_environmentVariables.last());
+ m_environmentVariables.last() = nameAndValue;
+ m_environmentVariables.append(static_cast<char*>(0));
+
+ m_environmentPointer = m_environmentVariables.data();
+ }
+
+ char* get(const char* name) const
+ {
+ for (size_t i = 0; m_environmentPointer[i]; ++i) {
+ if (char* value = valueIfVariableHasName(m_environmentPointer[i], name))
+ return value;
+ }
+ return 0;
+ }
+
+ // 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* 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());
+ }
+
+ char** environmentPointer() const { return m_environmentPointer; }
+
+private:
+ char *valueIfVariableHasName(const char* environmentVariable, const char* name) const
+ {
+ // Find the environment variable name.
+ char* equalsLocation = strchr(environmentVariable, '=');
+ ASSERT(equalsLocation);
+
+ size_t nameLength = equalsLocation - environmentVariable;
+ if (strncmp(environmentVariable, name, nameLength))
+ return 0;
+
+ return equalsLocation + 1;
+ }
+
+ char* 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 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));
+ }
+
+ char** m_environmentPointer;
+ Vector<char*> m_environmentVariables;
+
+ // These allocated strings will be freed in the destructor.
+ Vector<char*> m_allocatedStrings;
+};
+
+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);
+
+ NSBundle *webKit2Bundle = [NSBundle bundleWithIdentifier:@"com.apple.WebKit2"];
+ const char* bundlePath = [[webKit2Bundle executablePath] fileSystemRepresentation];
+
+ NSString *webProcessAppPath = [webKit2Bundle pathForAuxiliaryExecutable:@"WebProcess.app"];
+ NSString *webProcessAppExecutablePath = [[NSBundle bundleWithPath:webProcessAppPath] executablePath];
+
+ // 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* path = [webProcessAppExecutablePath fileSystemRepresentation];
+ const char* args[] = { path, bundlePath, "-type", processTypeAsString(m_launchOptions.processType), "-servicename", serviceName.data(), "-parentprocessname", processName(), 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;
+
+ posix_spawnattr_setflags(&attr, flags);
+
+ pid_t processIdentifier;
+
+ EnvironmentVariables environmentVariables;
+
+ if (m_launchOptions.processType == ProcessLauncher::PluginProcess) {
+ // We need to insert the plug-in process shim.
+ NSString *pluginProcessShimPathNSString = [[webProcessAppExecutablePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"PluginProcessShim.dylib"];
+ const char *pluginProcessShimPath = [pluginProcessShimPathNSString fileSystemRepresentation];
+
+ // Make sure that the file exists.
+ struct stat statBuf;
+ if (stat(pluginProcessShimPath, &statBuf) == 0 && (statBuf.st_mode & S_IFMT) == S_IFREG)
+ environmentVariables.appendValue("DYLD_INSERT_LIBRARIES", pluginProcessShimPath, ':');
+ }
+
+ int result = posix_spawn(&processIdentifier, path, 0, &attr, (char *const*)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;
+ }
+
+ // We've finished launching the process, message back to the main run loop.
+ RunLoop::main()->scheduleWork(WorkItem::create(this, &ProcessLauncher::didFinishLaunchingProcess, 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 0000000..8aac275
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/mac/ThreadLauncherMac.mm
@@ -0,0 +1,72 @@
+/*
+ * 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 "ThreadLauncher.h"
+
+#include "RunLoop.h"
+#include "WebProcess.h"
+#include "WebSystemInterface.h"
+#include <runtime/InitializeThreading.h>
+#include <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 0000000..7dff894
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp
@@ -0,0 +1,223 @@
+/*
+ * 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 "ProcessLauncher.h"
+
+#include "Connection.h"
+#include "CleanupHandler.h"
+#include "NotImplemented.h"
+#include "RunLoop.h"
+#include "WebProcess.h"
+#include <runtime/InitializeThreading.h>
+#include <string>
+#include <wtf/HashSet.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+#include <wtf/text/WTFString.h>
+
+#include <QApplication>
+#include <QDebug>
+#include <QFile>
+#include <QLocalServer>
+#include <QMetaType>
+#include <QProcess>
+#include <QString>
+
+#include <QtCore/qglobal.h>
+
+#include <sys/resource.h>
+#include <unistd.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+class ProcessLauncherHelper : public QObject {
+ Q_OBJECT
+public:
+ ~ProcessLauncherHelper();
+ void launch(WebKit::ProcessLauncher*);
+ QLocalSocket* takePendingConnection();
+ static ProcessLauncherHelper* instance();
+
+ const QString serverName() const { return m_server.serverName(); }
+
+private:
+ ProcessLauncherHelper();
+ QLocalServer m_server;
+ QList<WorkItem*> m_items;
+
+ Q_SLOT void newConnection();
+};
+
+Q_GLOBAL_STATIC(WTF::HashSet<QProcess*>, processes);
+
+static void cleanupAtExit()
+{
+ // Terminate our web process(es).
+ WTF::HashSet<QProcess*>::const_iterator end = processes()->end();
+ for (WTF::HashSet<QProcess*>::const_iterator it = processes()->begin(); it != end; ++it) {
+ QProcess* process = *it;
+ process->disconnect(process);
+ process->terminate();
+ if (!process->waitForFinished(200))
+ process->kill();
+ }
+
+ // Do not leave the socket file behind.
+ QLocalServer::removeServer(ProcessLauncherHelper::instance()->serverName());
+}
+
+class QtWebProcess : public QProcess
+{
+ Q_OBJECT
+public:
+ QtWebProcess(QObject* parent = 0)
+ : QProcess(parent)
+ {
+ static bool isRegistered = false;
+ if (!isRegistered) {
+ qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState");
+ isRegistered = true;
+ }
+
+ connect(this, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState)));
+ }
+
+private slots:
+ void processStateChanged(QProcess::ProcessState state);
+};
+
+void QtWebProcess::processStateChanged(QProcess::ProcessState state)
+{
+ QProcess* process = qobject_cast<QProcess*>(sender());
+ if (!process)
+ return;
+
+ if (state == QProcess::Running)
+ processes()->add(process);
+ else if (state == QProcess::NotRunning)
+ processes()->remove(process);
+}
+
+void ProcessLauncherHelper::launch(WebKit::ProcessLauncher* launcher)
+{
+ QString applicationPath = "%1 %2";
+
+ if (QFile::exists(QCoreApplication::applicationDirPath() + "/QtWebProcess")) {
+ applicationPath = applicationPath.arg(QCoreApplication::applicationDirPath() + "/QtWebProcess");
+ } else {
+ applicationPath = applicationPath.arg("QtWebProcess");
+ }
+
+ QString program(applicationPath.arg(m_server.serverName()));
+
+ QProcess* webProcess = new QtWebProcess();
+ webProcess->setProcessChannelMode(QProcess::ForwardedChannels);
+ webProcess->start(program);
+
+ if (!webProcess->waitForStarted()) {
+ qDebug() << "Failed to start" << program;
+ ASSERT_NOT_REACHED();
+ delete webProcess;
+ return;
+ }
+
+ setpriority(PRIO_PROCESS, webProcess->pid(), 10);
+
+ m_items.append(WorkItem::create(launcher, &WebKit::ProcessLauncher::didFinishLaunchingProcess, webProcess, m_server.serverName()).leakPtr());
+}
+
+QLocalSocket* ProcessLauncherHelper::takePendingConnection()
+{
+ return m_server.nextPendingConnection();
+}
+
+ProcessLauncherHelper::~ProcessLauncherHelper()
+{
+ m_server.close();
+}
+
+ProcessLauncherHelper::ProcessLauncherHelper()
+{
+ srandom(time(0));
+ if (!m_server.listen("QtWebKit" + QString::number(random()))) {
+ qDebug() << "Failed to create server socket.";
+ ASSERT_NOT_REACHED();
+ }
+ connect(&m_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
+}
+
+ProcessLauncherHelper* ProcessLauncherHelper::instance()
+{
+ static ProcessLauncherHelper* result = 0;
+ if (!result) {
+ result = new ProcessLauncherHelper();
+
+ // The purpose of the following line is to ensure that our static is initialized before the exit handler is installed.
+ processes()->clear();
+
+ atexit(cleanupAtExit);
+ }
+ return result;
+}
+
+void ProcessLauncherHelper::newConnection()
+{
+ ASSERT(!m_items.isEmpty());
+
+ m_items[0]->execute();
+ delete m_items[0];
+ m_items.pop_front();
+}
+
+void ProcessLauncher::launchProcess()
+{
+ ProcessLauncherHelper::instance()->launch(this);
+}
+
+void ProcessLauncher::terminateProcess()
+{
+ if (!m_processIdentifier)
+ return;
+
+ QObject::connect(m_processIdentifier, SIGNAL(finished(int)), m_processIdentifier, SLOT(deleteLater()), Qt::QueuedConnection);
+ m_processIdentifier->terminate();
+}
+
+QLocalSocket* ProcessLauncher::takePendingConnection()
+{
+ return ProcessLauncherHelper::instance()->takePendingConnection();
+}
+
+void ProcessLauncher::platformInvalidate()
+{
+ notImplemented();
+}
+
+} // 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 0000000..471a424
--- /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 "ThreadLauncher.h"
+
+#include "RunLoop.h"
+#include "WebProcess.h"
+#include <runtime/InitializeThreading.h>
+#include <wtf/Threading.h>
+
+#include <QApplication>
+#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("foo", 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;
+ }
+
+ QString serverIdentifier = QString::number(connectionIdentifier);
+ return serverIdentifier;
+}
+
+} // 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 0000000..7165a18
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/win/ProcessLauncherWin.cpp
@@ -0,0 +1,122 @@
+/*
+ * 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 "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, commandLine);
+ 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()->scheduleWork(WorkItem::create(this, &ProcessLauncher::didFinishLaunchingProcess, 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 0000000..b8b2f64
--- /dev/null
+++ b/Source/WebKit2/UIProcess/Launcher/win/ThreadLauncherWin.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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 "ThreadLauncher.h"
+
+#include "RunLoop.h"
+#include "WebProcess.h"
+#include <runtime/InitializeThreading.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