summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp')
-rw-r--r--Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp171
1 files changed, 50 insertions, 121 deletions
diff --git a/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp b/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp
index 7dff894..85c3651 100644
--- a/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp
+++ b/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp
@@ -24,20 +24,13 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "config.h"
#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>
@@ -45,52 +38,27 @@
#include <QMetaType>
#include <QProcess>
#include <QString>
-
#include <QtCore/qglobal.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
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
@@ -98,32 +66,20 @@ 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);
+protected:
+ virtual void setupChildProcess();
};
-void QtWebProcess::processStateChanged(QProcess::ProcessState state)
+void QtWebProcess::setupChildProcess()
{
- QProcess* process = qobject_cast<QProcess*>(sender());
- if (!process)
- return;
-
- if (state == QProcess::Running)
- processes()->add(process);
- else if (state == QProcess::NotRunning)
- processes()->remove(process);
+#if defined Q_OS_LINUX
+ prctl(PR_SET_PDEATHSIG, SIGKILL);
+#endif
}
-void ProcessLauncherHelper::launch(WebKit::ProcessLauncher* launcher)
+void ProcessLauncher::launchProcess()
{
QString applicationPath = "%1 %2";
@@ -133,12 +89,38 @@ void ProcessLauncherHelper::launch(WebKit::ProcessLauncher* launcher)
applicationPath = applicationPath.arg("QtWebProcess");
}
- QString program(applicationPath.arg(m_server.serverName()));
+ int sockets[2];
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 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;
+ }
+ }
+
+ QString program(applicationPath.arg(sockets[0]));
QProcess* webProcess = new QtWebProcess();
webProcess->setProcessChannelMode(QProcess::ForwardedChannels);
webProcess->start(program);
+ // 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;
+ }
+ }
+
if (!webProcess->waitForStarted()) {
qDebug() << "Failed to start" << program;
ASSERT_NOT_REACHED();
@@ -148,55 +130,7 @@ void ProcessLauncherHelper::launch(WebKit::ProcessLauncher* launcher)
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);
+ RunLoop::main()->scheduleWork(WorkItem::create(this, &WebKit::ProcessLauncher::didFinishLaunchingProcess, webProcess, sockets[1]));
}
void ProcessLauncher::terminateProcess()
@@ -208,14 +142,9 @@ void ProcessLauncher::terminateProcess()
m_processIdentifier->terminate();
}
-QLocalSocket* ProcessLauncher::takePendingConnection()
-{
- return ProcessLauncherHelper::instance()->takePendingConnection();
-}
-
void ProcessLauncher::platformInvalidate()
{
- notImplemented();
+
}
} // namespace WebKit