2 Copyright (C) 2012 Samsung Electronics
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
21 #include "ProcessLauncher.h"
23 #include "Connection.h"
24 #include "ProcessExecutablePath.h"
25 #include <WebCore/FileSystem.h>
26 #include <WebCore/ResourceHandle.h>
27 #include <WebCore/RunLoop.h>
28 #include <wtf/text/CString.h>
29 #include <wtf/text/WTFString.h>
31 #if ENABLE(TIZEN_WRT_LAUNCHING_PERFORMANCE)
32 #include "WebProcessMainEfl.h"
35 extern char** _ewkArgv;
38 using namespace WebCore;
42 #if ENABLE(TIZEN_WRT_LAUNCHING_PERFORMANCE)
50 class StatusForWRTLaunchingPerformance {
52 StatusForWRTLaunchingPerformance();
53 void setSkipExec(bool skipExec) { m_skipExec = skipExec; }
54 bool isInitialFork() { return m_isInitialFork; }
55 void setInitialForkAsFalse() { m_isInitialFork = false; }
56 bool skipExec() { return m_skipExec; }
57 bool isParentProcess() { return m_processType == PARENT_PROCESS; }
58 bool isChildProcess() { return m_processType == CHILD_PROCESS; }
59 pid_t pid() { return m_pid; }
61 void callWebProcessMain();
62 int socket(int index) { return m_sockets[index]; }
73 StatusForWRTLaunchingPerformance::StatusForWRTLaunchingPerformance()
74 : m_isInitialFork(true)
76 , m_processType(PROCESS_TYPE_NONE)
79 m_argv[0] = m_argv[1] = m_argv[2] = 0;
80 m_sockets[0] = m_sockets[1] = -1;
83 void StatusForWRTLaunchingPerformance::forkProcess()
85 if (!m_isInitialFork || !m_skipExec) {
86 m_processType = PARENT_PROCESS;
90 if (socketpair(AF_UNIX, SOCK_STREAM, 0, m_sockets) < 0) {
96 if (!m_pid) { // child process
98 m_processType = CHILD_PROCESS;
100 else if (m_pid > 0) {
102 m_processType = PARENT_PROCESS;
105 ASSERT_NOT_REACHED();
110 void StatusForWRTLaunchingPerformance::callWebProcessMain()
112 if (m_processType == CHILD_PROCESS) {
113 String socket = String::format("%d", m_sockets[0]);
114 String executablePath = "/usr/bin/WebProcess";
115 m_argv[0] = strdup(executablePath.utf8().data());
116 if (_ewkArgc > 0 && _ewkArgv && _ewkArgv[0]) {
117 int maxLen = strlen(_ewkArgv[0]);
119 strncpy(_ewkArgv[0], m_argv[0], maxLen);
120 _ewkArgv[0][maxLen] = 0;
123 m_argv[1] = strdup(socket.utf8().data());
124 WebProcessMainEfl(2, m_argv);
128 static StatusForWRTLaunchingPerformance& getStatus()
130 static StatusForWRTLaunchingPerformance status;
134 void ProcessLauncher::setSkipExec(bool skipExec)
136 getStatus().setSkipExec(skipExec);
139 bool ProcessLauncher::isInitialFork()
141 return getStatus().isInitialFork();
144 bool ProcessLauncher::isParentProcess()
146 return getStatus().isParentProcess();
149 bool ProcessLauncher::isChildProcess()
151 return getStatus().isChildProcess();
154 void ProcessLauncher::forkProcess()
156 getStatus().forkProcess();
159 void ProcessLauncher::callWebProcessMain()
161 getStatus().callWebProcessMain();
165 void ProcessLauncher::launchProcess()
167 #if ENABLE(TIZEN_WRT_LAUNCHING_PERFORMANCE)
168 if (getStatus().isInitialFork() && getStatus().skipExec()) {
169 getStatus().setInitialForkAsFalse();
170 if (getStatus().isParentProcess()) { // parent process;
171 m_processIdentifier = getStatus().pid();
172 // We've finished launching the process, message back to the main run loop.
173 RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, getStatus().pid() , getStatus().socket(1)));
180 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
181 ASSERT_NOT_REACHED();
186 #if ENABLE(TIZEN_WRT_LAUNCHING_PERFORMANCE)
187 getStatus().setInitialForkAsFalse();
189 if (!pid) { // child process
191 #if ENABLE(TIZEN_WEBKIT2_GIVE_SEPARATE_PROCESS_GROUP_ID_TO_WEBPROCESS)
194 String socket = String::format("%d", sockets[0]);
195 String executablePath;
196 switch (m_launchOptions.processType) {
198 #if ENABLE(TIZEN_PROCESS_PERMISSION_CONTROL)
199 if (!m_launchOptions.customExecutablePath.isEmpty()) {
200 executablePath = m_launchOptions.customExecutablePath;
201 TIZEN_LOGI("web process executable path: %s", executablePath.utf8().data());
204 executablePath = executablePathOfWebProcess();
207 #if ENABLE(TIZEN_PROCESS_PERMISSION_CONTROL)
209 // this env is used for tizen wrt process pool, and has highest priority for use.
210 const char* pathForProcessPool = getenv("PLUGIN_PROCESS_EXECUTABLE_PATH_FOR_PROCESS_POOL");
211 if (pathForProcessPool) {
212 executablePath = String::fromUTF8(pathForProcessPool);
213 TIZEN_LOGI("plugin process executable path: %s", executablePath.utf8().data());
218 if (!m_launchOptions.customExecutablePath.isEmpty()) {
219 executablePath = m_launchOptions.customExecutablePath;
220 TIZEN_LOGI("plugin process executable path: %s", executablePath.utf8().data());
223 executablePath = executablePathOfPluginProcess();
226 ASSERT_NOT_REACHED();
231 if (m_launchOptions.processCmdPrefix.isEmpty())
233 execl(executablePath.utf8().data(), executablePath.utf8().data(), socket.utf8().data(), static_cast<char*>(0));
236 String cmd = makeString(m_launchOptions.processCmdPrefix, ' ', executablePath, ' ', socket);
237 if (system(cmd.utf8().data()) == -1) {
238 ASSERT_NOT_REACHED();
243 } else if (pid > 0) { // parent process;
245 m_processIdentifier = pid;
246 // We've finished launching the process, message back to the main run loop.
247 RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, pid, sockets[1]));
249 ASSERT_NOT_REACHED();
254 void ProcessLauncher::terminateProcess()
256 if (!m_processIdentifier)
258 kill(m_processIdentifier, SIGKILL);
261 void ProcessLauncher::platformInvalidate()
265 } // namespace WebKit