|
1 /* |
|
2 * Copyright (C) 2010 Apple Inc. All rights reserved. |
|
3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
|
4 * |
|
5 * Redistribution and use in source and binary forms, with or without |
|
6 * modification, are permitted provided that the following conditions |
|
7 * are met: |
|
8 * 1. Redistributions of source code must retain the above copyright |
|
9 * notice, this list of conditions and the following disclaimer. |
|
10 * 2. Redistributions in binary form must reproduce the above copyright |
|
11 * notice, this list of conditions and the following disclaimer in the |
|
12 * documentation and/or other materials provided with the distribution. |
|
13 * |
|
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
|
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
|
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
|
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
|
24 * THE POSSIBILITY OF SUCH DAMAGE. |
|
25 */ |
|
26 |
|
27 #include "ProcessLauncher.h" |
|
28 |
|
29 #include "Connection.h" |
|
30 #include "RunLoop.h" |
|
31 #include "WebProcess.h" |
|
32 #include <WebCore/PlatformString.h> |
|
33 #include <runtime/InitializeThreading.h> |
|
34 #include <string> |
|
35 #include <wtf/PassRefPtr.h> |
|
36 #include <wtf/Threading.h> |
|
37 |
|
38 #if USE(MEEGOTOUCH) |
|
39 #include <meegotouch/MComponentData> |
|
40 #endif |
|
41 |
|
42 #include <QApplication> |
|
43 #include <QDebug> |
|
44 #include <QLocalServer> |
|
45 #include <QProcess> |
|
46 |
|
47 #include <QtCore/qglobal.h> |
|
48 |
|
49 #include <sys/resource.h> |
|
50 #include <unistd.h> |
|
51 |
|
52 #if !defined(QWEBKIT_EXPORT) |
|
53 # if defined(QT_SHARED) |
|
54 # define QWEBKIT_EXPORT Q_DECL_EXPORT |
|
55 # else |
|
56 # define QWEBKIT_EXPORT |
|
57 # endif |
|
58 #endif |
|
59 |
|
60 using namespace WebCore; |
|
61 |
|
62 namespace WebKit { |
|
63 |
|
64 class ProcessLauncherHelper : public QObject { |
|
65 Q_OBJECT |
|
66 public: |
|
67 void launch(WebKit::ProcessLauncher*); |
|
68 QLocalSocket* takePendingConnection(); |
|
69 static ProcessLauncherHelper* instance(); |
|
70 private: |
|
71 ProcessLauncherHelper(); |
|
72 QLocalServer m_server; |
|
73 QList<WorkItem*> m_items; |
|
74 |
|
75 Q_SLOT void newConnection(); |
|
76 }; |
|
77 |
|
78 void ProcessLauncherHelper::launch(WebKit::ProcessLauncher* launcher) |
|
79 { |
|
80 QString program("QtWebProcess " + m_server.serverName()); |
|
81 |
|
82 QProcess* webProcess = new QProcess(); |
|
83 webProcess->start(program); |
|
84 |
|
85 if (!webProcess->waitForStarted()) { |
|
86 qDebug() << "Failed to start" << program; |
|
87 ASSERT_NOT_REACHED(); |
|
88 delete webProcess; |
|
89 return; |
|
90 } |
|
91 |
|
92 setpriority(PRIO_PROCESS, webProcess->pid(), 10); |
|
93 |
|
94 m_items.append(WorkItem::create(launcher, &WebKit::ProcessLauncher::didFinishLaunchingProcess, webProcess, m_server.serverName()).leakPtr()); |
|
95 } |
|
96 |
|
97 QLocalSocket* ProcessLauncherHelper::takePendingConnection() |
|
98 { |
|
99 return m_server.nextPendingConnection(); |
|
100 } |
|
101 |
|
102 ProcessLauncherHelper::ProcessLauncherHelper() |
|
103 { |
|
104 srandom(time(0)); |
|
105 if (!m_server.listen("QtWebKit" + QString::number(random()))) { |
|
106 qDebug() << "Failed to create server socket."; |
|
107 ASSERT_NOT_REACHED(); |
|
108 } |
|
109 connect(&m_server, SIGNAL(newConnection()), this, SLOT(newConnection())); |
|
110 } |
|
111 |
|
112 ProcessLauncherHelper* ProcessLauncherHelper::instance() |
|
113 { |
|
114 static ProcessLauncherHelper* result = new ProcessLauncherHelper(); |
|
115 return result; |
|
116 } |
|
117 |
|
118 void ProcessLauncherHelper::newConnection() |
|
119 { |
|
120 ASSERT(!m_items.isEmpty()); |
|
121 |
|
122 m_items[0]->execute(); |
|
123 delete m_items[0]; |
|
124 m_items.pop_front(); |
|
125 } |
|
126 |
|
127 void ProcessLauncher::launchProcess() |
|
128 { |
|
129 ProcessLauncherHelper::instance()->launch(this); |
|
130 } |
|
131 |
|
132 void ProcessLauncher::terminateProcess() |
|
133 { |
|
134 if (!m_processIdentifier) |
|
135 return; |
|
136 |
|
137 QObject::connect(m_processIdentifier, SIGNAL(finished(int)), m_processIdentifier, SLOT(deleteLater()), Qt::QueuedConnection); |
|
138 m_processIdentifier->kill(); |
|
139 } |
|
140 |
|
141 QLocalSocket* ProcessLauncher::takePendingConnection() |
|
142 { |
|
143 return ProcessLauncherHelper::instance()->takePendingConnection(); |
|
144 } |
|
145 |
|
146 static void* webThreadBody(void* /* context */) |
|
147 { |
|
148 // Initialization |
|
149 JSC::initializeThreading(); |
|
150 WTF::initializeMainThread(); |
|
151 |
|
152 // FIXME: We do not support threaded mode for now. |
|
153 |
|
154 WebProcess::shared().initialize("foo", RunLoop::current()); |
|
155 RunLoop::run(); |
|
156 |
|
157 return 0; |
|
158 } |
|
159 |
|
160 CoreIPC::Connection::Identifier ProcessLauncher::createWebThread() |
|
161 { |
|
162 srandom(time(0)); |
|
163 int connectionIdentifier = random(); |
|
164 |
|
165 if (!createThread(webThreadBody, reinterpret_cast<void*>(connectionIdentifier), "WebKit2: WebThread")) { |
|
166 qWarning() << "failed starting thread"; |
|
167 return 0; |
|
168 } |
|
169 |
|
170 QString serverIdentifier = QString::number(connectionIdentifier); |
|
171 return serverIdentifier; |
|
172 } |
|
173 |
|
174 } // namespace WebKit |
|
175 |
|
176 QWEBKIT_EXPORT int webProcessMain(int argc, char** argv) |
|
177 { |
|
178 QApplication* app = new QApplication(argc, argv); |
|
179 |
|
180 #if USE(MEEGOTOUCH) |
|
181 new MComponentData(argc, argv); |
|
182 #endif |
|
183 |
|
184 srandom(time(0)); |
|
185 |
|
186 JSC::initializeThreading(); |
|
187 WTF::initializeMainThread(); |
|
188 RunLoop::initializeMainRunLoop(); |
|
189 |
|
190 // Create the connection. |
|
191 QString identifier(app->arguments().size() > 1 ? app->arguments().at(1) : ""); |
|
192 WebKit::WebProcess::shared().initialize(identifier, RunLoop::main()); |
|
193 |
|
194 RunLoop::run(); |
|
195 |
|
196 // FIXME: Do more cleanup here. |
|
197 |
|
198 return 0; |
|
199 } |
|
200 |
|
201 #include "ProcessLauncherQt.moc" |