diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp')
-rw-r--r-- | Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp | 171 |
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 |