Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: content/browser/child_process_launcher.cc

Issue 7006006: Replace OS_LINUX ifdefs with OS_POSIX & !OS_MACOSX, TOOLKIT_USES_GTK, or (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | content/browser/content_browser_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/child_process_launcher.h" 5 #include "content/browser/child_process_launcher.h"
6 6
7 #include <utility> // For std::pair. 7 #include <utility> // For std::pair.
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/synchronization/lock.h" 12 #include "base/synchronization/lock.h"
13 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
14 #include "content/browser/browser_thread.h" 14 #include "content/browser/browser_thread.h"
15 #include "content/browser/content_browser_client.h" 15 #include "content/browser/content_browser_client.h"
16 #include "content/common/chrome_descriptors.h" 16 #include "content/common/chrome_descriptors.h"
17 #include "content/common/content_switches.h" 17 #include "content/common/content_switches.h"
18 #include "content/common/process_watcher.h" 18 #include "content/common/process_watcher.h"
19 #include "content/common/result_codes.h" 19 #include "content/common/result_codes.h"
20 20
21 #if defined(OS_WIN) 21 #if defined(OS_WIN)
22 #include "base/file_path.h" 22 #include "base/file_path.h"
23 #include "content/common/sandbox_policy.h" 23 #include "content/common/sandbox_policy.h"
24 #elif defined(OS_LINUX) 24 #elif defined(OS_MACOSX)
25 #include "chrome/browser/mach_broker_mac.h"
26 #elif defined(OS_POSIX)
25 #include "base/memory/singleton.h" 27 #include "base/memory/singleton.h"
26 #include "content/browser/zygote_host_linux.h" 28 #include "content/browser/zygote_host_linux.h"
27 #include "content/browser/renderer_host/render_sandbox_host_linux.h" 29 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
28 #endif 30 #endif
29 31
30 #if defined(OS_MACOSX)
31 #include "chrome/browser/mach_broker_mac.h"
32 #endif
33
34 #if defined(OS_POSIX) 32 #if defined(OS_POSIX)
35 #include "base/global_descriptors_posix.h" 33 #include "base/global_descriptors_posix.h"
36 #endif 34 #endif
37 35
38 // Having the functionality of ChildProcessLauncher be in an internal 36 // Having the functionality of ChildProcessLauncher be in an internal
39 // ref counted object allows us to automatically terminate the process when the 37 // ref counted object allows us to automatically terminate the process when the
40 // parent class destructs, while still holding on to state that we need. 38 // parent class destructs, while still holding on to state that we need.
41 class ChildProcessLauncher::Context 39 class ChildProcessLauncher::Context
42 : public base::RefCountedThreadSafe<ChildProcessLauncher::Context> { 40 : public base::RefCountedThreadSafe<ChildProcessLauncher::Context> {
43 public: 41 public:
44 Context() 42 Context()
45 : client_(NULL), 43 : client_(NULL),
46 client_thread_id_(BrowserThread::UI), 44 client_thread_id_(BrowserThread::UI),
47 starting_(true), 45 starting_(true),
48 terminate_child_on_shutdown_(true) 46 terminate_child_on_shutdown_(true)
49 #if defined(OS_LINUX) 47 #if defined(OS_POSIX) && !defined(OS_MACOSX)
50 , zygote_(false) 48 , zygote_(false)
51 #endif 49 #endif
52 { 50 {
53 } 51 }
54 52
55 void Launch( 53 void Launch(
56 #if defined(OS_WIN) 54 #if defined(OS_WIN)
57 const FilePath& exposed_dir, 55 const FilePath& exposed_dir,
58 #elif defined(OS_POSIX) 56 #elif defined(OS_POSIX)
59 bool use_zygote, 57 bool use_zygote,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 const base::environment_vector& env, 106 const base::environment_vector& env,
109 int ipcfd, 107 int ipcfd,
110 #endif 108 #endif
111 CommandLine* cmd_line) { 109 CommandLine* cmd_line) {
112 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); 110 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line);
113 base::ProcessHandle handle = base::kNullProcessHandle; 111 base::ProcessHandle handle = base::kNullProcessHandle;
114 #if defined(OS_WIN) 112 #if defined(OS_WIN)
115 handle = sandbox::StartProcessWithAccess(cmd_line, exposed_dir); 113 handle = sandbox::StartProcessWithAccess(cmd_line, exposed_dir);
116 #elif defined(OS_POSIX) 114 #elif defined(OS_POSIX)
117 115
118 #if defined(OS_LINUX) 116 #if defined(OS_POSIX) && !defined(OS_MACOSX)
119 // On Linux, we need to add some extra file descriptors for crash handling. 117 // On Linux, we need to add some extra file descriptors for crash handling.
120 std::string process_type = 118 std::string process_type =
121 cmd_line->GetSwitchValueASCII(switches::kProcessType); 119 cmd_line->GetSwitchValueASCII(switches::kProcessType);
122 int crash_signal_fd = 120 int crash_signal_fd =
123 content::GetContentClient()->browser()->GetCrashSignalFD(process_type); 121 content::GetContentClient()->browser()->GetCrashSignalFD(process_type);
124 if (use_zygote) { 122 if (use_zygote) {
125 base::GlobalDescriptors::Mapping mapping; 123 base::GlobalDescriptors::Mapping mapping;
126 mapping.push_back(std::pair<uint32_t, int>(kPrimaryIPCChannel, ipcfd)); 124 mapping.push_back(std::pair<uint32_t, int>(kPrimaryIPCChannel, ipcfd));
127 if (crash_signal_fd >= 0) { 125 if (crash_signal_fd >= 0) {
128 mapping.push_back(std::pair<uint32_t, int>(kCrashDumpSignal, 126 mapping.push_back(std::pair<uint32_t, int>(kCrashDumpSignal,
129 crash_signal_fd)); 127 crash_signal_fd));
130 } 128 }
131 handle = ZygoteHost::GetInstance()->ForkRenderer(cmd_line->argv(), 129 handle = ZygoteHost::GetInstance()->ForkRenderer(cmd_line->argv(),
132 mapping); 130 mapping);
133 } else 131 } else
134 // Fall through to the normal posix case below when we're not zygoting. 132 // Fall through to the normal posix case below when we're not zygoting.
135 #endif 133 #endif
136 { 134 {
137 base::file_handle_mapping_vector fds_to_map; 135 base::file_handle_mapping_vector fds_to_map;
138 fds_to_map.push_back(std::make_pair( 136 fds_to_map.push_back(std::make_pair(
139 ipcfd, 137 ipcfd,
140 kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); 138 kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor));
141 139
142 #if defined(OS_LINUX) 140 #if defined(OS_POSIX) && !defined(OS_MACOSX)
143 if (crash_signal_fd >= 0) { 141 if (crash_signal_fd >= 0) {
144 fds_to_map.push_back(std::make_pair( 142 fds_to_map.push_back(std::make_pair(
145 crash_signal_fd, 143 crash_signal_fd,
146 kCrashDumpSignal + base::GlobalDescriptors::kBaseDescriptor)); 144 kCrashDumpSignal + base::GlobalDescriptors::kBaseDescriptor));
147 } 145 }
148 if (process_type == switches::kRendererProcess) { 146 if (process_type == switches::kRendererProcess) {
149 const int sandbox_fd = 147 const int sandbox_fd =
150 RenderSandboxHostLinux::GetInstance()->GetRendererSocket(); 148 RenderSandboxHostLinux::GetInstance()->GetRendererSocket();
151 fds_to_map.push_back(std::make_pair( 149 fds_to_map.push_back(std::make_pair(
152 sandbox_fd, 150 sandbox_fd,
153 kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); 151 kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor));
154 } 152 }
155 #endif // defined(OS_LINUX) 153 #endif // defined(OS_POSIX) && !defined(OS_MACOSX)
156 154
157 bool launched = false; 155 bool launched = false;
158 #if defined(OS_MACOSX) 156 #if defined(OS_MACOSX)
159 // It is possible for the child process to die immediately after 157 // It is possible for the child process to die immediately after
160 // launching. To prevent leaking MachBroker map entries in this case, 158 // launching. To prevent leaking MachBroker map entries in this case,
161 // lock around all of LaunchApp(). If the child dies, the death 159 // lock around all of LaunchApp(). If the child dies, the death
162 // notification will be processed by the MachBroker after the call to 160 // notification will be processed by the MachBroker after the call to
163 // AddPlaceholderForPid(), enabling proper cleanup. 161 // AddPlaceholderForPid(), enabling proper cleanup.
164 { // begin scope for AutoLock 162 { // begin scope for AutoLock
165 MachBroker* broker = MachBroker::GetInstance(); 163 MachBroker* broker = MachBroker::GetInstance();
(...skipping 15 matching lines...) Expand all
181 if (!launched) 179 if (!launched)
182 handle = base::kNullProcessHandle; 180 handle = base::kNullProcessHandle;
183 } 181 }
184 #endif // else defined(OS_POSIX) 182 #endif // else defined(OS_POSIX)
185 183
186 BrowserThread::PostTask( 184 BrowserThread::PostTask(
187 client_thread_id_, FROM_HERE, 185 client_thread_id_, FROM_HERE,
188 NewRunnableMethod( 186 NewRunnableMethod(
189 this, 187 this,
190 &ChildProcessLauncher::Context::Notify, 188 &ChildProcessLauncher::Context::Notify,
191 #if defined(OS_LINUX) 189 #if defined(OS_POSIX) && !defined(OS_MACOSX)
192 use_zygote, 190 use_zygote,
193 #endif 191 #endif
194 handle)); 192 handle));
195 } 193 }
196 194
197 void Notify( 195 void Notify(
198 #if defined(OS_LINUX) 196 #if defined(OS_POSIX) && !defined(OS_MACOSX)
199 bool zygote, 197 bool zygote,
200 #endif 198 #endif
201 base::ProcessHandle handle) { 199 base::ProcessHandle handle) {
202 starting_ = false; 200 starting_ = false;
203 process_.set_handle(handle); 201 process_.set_handle(handle);
204 #if defined(OS_LINUX) 202 #if defined(OS_POSIX) && !defined(OS_MACOSX)
205 zygote_ = zygote; 203 zygote_ = zygote;
206 #endif 204 #endif
207 if (client_) { 205 if (client_) {
208 client_->OnProcessLaunched(); 206 client_->OnProcessLaunched();
209 } else { 207 } else {
210 Terminate(); 208 Terminate();
211 } 209 }
212 } 210 }
213 211
214 void Terminate() { 212 void Terminate() {
215 if (!process_.handle()) 213 if (!process_.handle())
216 return; 214 return;
217 215
218 if (!terminate_child_on_shutdown_) 216 if (!terminate_child_on_shutdown_)
219 return; 217 return;
220 218
221 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So 219 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So
222 // don't this on the UI/IO threads. 220 // don't this on the UI/IO threads.
223 BrowserThread::PostTask( 221 BrowserThread::PostTask(
224 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 222 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
225 NewRunnableFunction( 223 NewRunnableFunction(
226 &ChildProcessLauncher::Context::TerminateInternal, 224 &ChildProcessLauncher::Context::TerminateInternal,
227 #if defined(OS_LINUX) 225 #if defined(OS_POSIX) && !defined(OS_MACOSX)
228 zygote_, 226 zygote_,
229 #endif 227 #endif
230 process_.handle())); 228 process_.handle()));
231 process_.set_handle(base::kNullProcessHandle); 229 process_.set_handle(base::kNullProcessHandle);
232 } 230 }
233 231
234 void SetProcessBackgrounded(bool background) { 232 void SetProcessBackgrounded(bool background) {
235 DCHECK(!starting_); 233 DCHECK(!starting_);
236 process_.SetProcessBackgrounded(background); 234 process_.SetProcessBackgrounded(background);
237 } 235 }
238 236
239 // TODO(apatrick): Remove this ASAP. http://crbog.com/81449 shows that this is 237 // TODO(apatrick): Remove this ASAP. http://crbog.com/81449 shows that this is
240 // called before later calling null. Disable optimization to try and get more 238 // called before later calling null. Disable optimization to try and get more
241 // information about what happened here. 239 // information about what happened here.
242 #if defined(OS_WIN) 240 #if defined(OS_WIN)
243 #pragma optimize("", off) 241 #pragma optimize("", off)
244 #endif 242 #endif
245 243
246 static void TerminateInternal( 244 static void TerminateInternal(
247 #if defined(OS_LINUX) 245 #if defined(OS_POSIX) && !defined(OS_MACOSX)
248 bool zygote, 246 bool zygote,
249 #endif 247 #endif
250 base::ProcessHandle handle) { 248 base::ProcessHandle handle) {
251 base::Process process(handle); 249 base::Process process(handle);
252 // Client has gone away, so just kill the process. Using exit code 0 250 // Client has gone away, so just kill the process. Using exit code 0
253 // means that UMA won't treat this as a crash. 251 // means that UMA won't treat this as a crash.
254 process.Terminate(ResultCodes::NORMAL_EXIT); 252 process.Terminate(ResultCodes::NORMAL_EXIT);
255 // On POSIX, we must additionally reap the child. 253 // On POSIX, we must additionally reap the child.
256 #if defined(OS_POSIX) 254 #if defined(OS_POSIX)
257 #if defined(OS_LINUX) 255 #if !defined(OS_MACOSX)
258 if (zygote) { 256 if (zygote) {
259 // If the renderer was created via a zygote, we have to proxy the reaping 257 // If the renderer was created via a zygote, we have to proxy the reaping
260 // through the zygote process. 258 // through the zygote process.
261 ZygoteHost::GetInstance()->EnsureProcessTerminated(handle); 259 ZygoteHost::GetInstance()->EnsureProcessTerminated(handle);
262 } else 260 } else
263 #endif // OS_LINUX 261 #endif // !OS_MACOSX
264 { 262 {
265 ProcessWatcher::EnsureProcessTerminated(handle); 263 ProcessWatcher::EnsureProcessTerminated(handle);
266 } 264 }
267 #endif // OS_POSIX 265 #endif // OS_POSIX
268 process.Close(); 266 process.Close();
269 } 267 }
270 268
271 #if defined(OS_WIN) 269 #if defined(OS_WIN)
272 #pragma optimize("", on) 270 #pragma optimize("", on)
273 #endif 271 #endif
274 272
275 Client* client_; 273 Client* client_;
276 BrowserThread::ID client_thread_id_; 274 BrowserThread::ID client_thread_id_;
277 base::Process process_; 275 base::Process process_;
278 bool starting_; 276 bool starting_;
279 // Controls whether the child process should be terminated on browser 277 // Controls whether the child process should be terminated on browser
280 // shutdown. Default behavior is to terminate the child. 278 // shutdown. Default behavior is to terminate the child.
281 bool terminate_child_on_shutdown_; 279 bool terminate_child_on_shutdown_;
282 280
283 #if defined(OS_LINUX) 281 #if defined(OS_POSIX) && !defined(OS_MACOSX)
284 bool zygote_; 282 bool zygote_;
285 #endif 283 #endif
286 }; 284 };
287 285
288 286
289 ChildProcessLauncher::ChildProcessLauncher( 287 ChildProcessLauncher::ChildProcessLauncher(
290 #if defined(OS_WIN) 288 #if defined(OS_WIN)
291 const FilePath& exposed_dir, 289 const FilePath& exposed_dir,
292 #elif defined(OS_POSIX) 290 #elif defined(OS_POSIX)
293 bool use_zygote, 291 bool use_zygote,
(...skipping 25 matching lines...) Expand all
319 317
320 base::ProcessHandle ChildProcessLauncher::GetHandle() { 318 base::ProcessHandle ChildProcessLauncher::GetHandle() {
321 DCHECK(!context_->starting_); 319 DCHECK(!context_->starting_);
322 return context_->process_.handle(); 320 return context_->process_.handle();
323 } 321 }
324 322
325 base::TerminationStatus ChildProcessLauncher::GetChildTerminationStatus( 323 base::TerminationStatus ChildProcessLauncher::GetChildTerminationStatus(
326 int* exit_code) { 324 int* exit_code) {
327 base::TerminationStatus status; 325 base::TerminationStatus status;
328 base::ProcessHandle handle = context_->process_.handle(); 326 base::ProcessHandle handle = context_->process_.handle();
329 #if defined(OS_LINUX) 327 #if defined(OS_POSIX) && !defined(OS_MACOSX)
330 if (context_->zygote_) { 328 if (context_->zygote_) {
331 status = ZygoteHost::GetInstance()->GetTerminationStatus(handle, exit_code); 329 status = ZygoteHost::GetInstance()->GetTerminationStatus(handle, exit_code);
332 } else 330 } else
333 #endif 331 #endif
334 { 332 {
335 status = base::GetTerminationStatus(handle, exit_code); 333 status = base::GetTerminationStatus(handle, exit_code);
336 } 334 }
337 335
338 // POSIX: If the process crashed, then the kernel closed the socket 336 // POSIX: If the process crashed, then the kernel closed the socket
339 // for it and so the child has already died by the time we get 337 // for it and so the child has already died by the time we get
(...skipping 15 matching lines...) Expand all
355 &ChildProcessLauncher::Context::SetProcessBackgrounded, 353 &ChildProcessLauncher::Context::SetProcessBackgrounded,
356 background)); 354 background));
357 } 355 }
358 356
359 void ChildProcessLauncher::SetTerminateChildOnShutdown( 357 void ChildProcessLauncher::SetTerminateChildOnShutdown(
360 bool terminate_on_shutdown) { 358 bool terminate_on_shutdown) {
361 if (context_) 359 if (context_)
362 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); 360 context_->set_terminate_child_on_shutdown(terminate_on_shutdown);
363 } 361 }
364 362
OLDNEW
« no previous file with comments | « no previous file | content/browser/content_browser_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698