OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 int child_process_id, | 81 int child_process_id, |
82 Client* client) { | 82 Client* client) { |
83 client_ = client; | 83 client_ = client; |
84 | 84 |
85 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); | 85 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); |
86 | 86 |
87 #if defined(OS_ANDROID) | 87 #if defined(OS_ANDROID) |
88 // We need to close the client end of the IPC channel to reliably detect | 88 // We need to close the client end of the IPC channel to reliably detect |
89 // child termination. We will close this fd after we create the child | 89 // child termination. We will close this fd after we create the child |
90 // process which is asynchronous on Android. | 90 // process which is asynchronous on Android. |
91 ipcfd_ = delegate->GetIpcFd(); | 91 ipcfd_.reset(delegate->TakeIpcFd().release()); |
92 #endif | 92 #endif |
93 BrowserThread::PostTask( | 93 BrowserThread::PostTask( |
94 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 94 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, |
95 base::Bind( | 95 base::Bind( |
96 &Context::LaunchInternal, | 96 &Context::LaunchInternal, |
97 make_scoped_refptr(this), | 97 make_scoped_refptr(this), |
98 client_thread_id_, | 98 client_thread_id_, |
99 child_process_id, | 99 child_process_id, |
100 delegate, | 100 delegate, |
101 cmd_line)); | 101 cmd_line)); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 // |this_object| is NOT thread safe. Only use it to post a task back. | 171 // |this_object| is NOT thread safe. Only use it to post a task back. |
172 scoped_refptr<Context> this_object, | 172 scoped_refptr<Context> this_object, |
173 BrowserThread::ID client_thread_id, | 173 BrowserThread::ID client_thread_id, |
174 int child_process_id, | 174 int child_process_id, |
175 SandboxedProcessLauncherDelegate* delegate, | 175 SandboxedProcessLauncherDelegate* delegate, |
176 base::CommandLine* cmd_line) { | 176 base::CommandLine* cmd_line) { |
177 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); | 177 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); |
178 #if defined(OS_WIN) | 178 #if defined(OS_WIN) |
179 bool launch_elevated = delegate->ShouldLaunchElevated(); | 179 bool launch_elevated = delegate->ShouldLaunchElevated(); |
180 #elif defined(OS_ANDROID) | 180 #elif defined(OS_ANDROID) |
181 int ipcfd = delegate->GetIpcFd(); | 181 // Uses |ipcfd_| instead of |ipcfd| on Android. |
182 #elif defined(OS_MACOSX) | 182 #elif defined(OS_MACOSX) |
183 base::EnvironmentMap env = delegate->GetEnvironment(); | 183 base::EnvironmentMap env = delegate->GetEnvironment(); |
184 int ipcfd = delegate->GetIpcFd(); | 184 base::ScopedFD ipcfd = delegate->TakeIpcFd(); |
185 #elif defined(OS_POSIX) | 185 #elif defined(OS_POSIX) |
186 bool use_zygote = delegate->ShouldUseZygote(); | 186 bool use_zygote = delegate->ShouldUseZygote(); |
187 base::EnvironmentMap env = delegate->GetEnvironment(); | 187 base::EnvironmentMap env = delegate->GetEnvironment(); |
188 int ipcfd = delegate->GetIpcFd(); | 188 base::ScopedFD ipcfd = delegate->TakeIpcFd(); |
189 #endif | 189 #endif |
190 scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line); | 190 scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line); |
191 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); | 191 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); |
192 | 192 |
193 #if defined(OS_WIN) | 193 #if defined(OS_WIN) |
194 base::ProcessHandle handle = base::kNullProcessHandle; | 194 base::ProcessHandle handle = base::kNullProcessHandle; |
195 if (launch_elevated) { | 195 if (launch_elevated) { |
196 base::LaunchOptions options; | 196 base::LaunchOptions options; |
197 options.start_hidden = true; | 197 options.start_hidden = true; |
198 base::LaunchElevatedProcess(*cmd_line, options, &handle); | 198 base::LaunchElevatedProcess(*cmd_line, options, &handle); |
199 } else { | 199 } else { |
200 handle = StartSandboxedProcess(delegate, cmd_line); | 200 handle = StartSandboxedProcess(delegate, cmd_line); |
201 } | 201 } |
202 #elif defined(OS_POSIX) | 202 #elif defined(OS_POSIX) |
203 std::string process_type = | 203 std::string process_type = |
204 cmd_line->GetSwitchValueASCII(switches::kProcessType); | 204 cmd_line->GetSwitchValueASCII(switches::kProcessType); |
205 scoped_ptr<FileDescriptorInfo> files_to_register( | 205 scoped_ptr<FileDescriptorInfo> files_to_register( |
206 FileDescriptorInfoImpl::Create()); | 206 FileDescriptorInfoImpl::Create()); |
207 files_to_register->Share(kPrimaryIPCChannel, ipcfd); | 207 |
| 208 #if defined(OS_ANDROID) |
| 209 files_to_register->Share(kPrimaryIPCChannel, this_object->ipcfd_.get()); |
| 210 #else |
| 211 files_to_register->Transfer(kPrimaryIPCChannel, ipcfd.Pass()); |
| 212 #endif |
208 base::StatsTable* stats_table = base::StatsTable::current(); | 213 base::StatsTable* stats_table = base::StatsTable::current(); |
209 if (stats_table && | 214 if (stats_table && |
210 base::SharedMemory::IsHandleValid( | 215 base::SharedMemory::IsHandleValid( |
211 stats_table->GetSharedMemoryHandle())) { | 216 stats_table->GetSharedMemoryHandle())) { |
212 base::FileDescriptor fd = stats_table->GetSharedMemoryHandle(); | 217 base::FileDescriptor fd = stats_table->GetSharedMemoryHandle(); |
213 DCHECK(!fd.auto_close); | 218 DCHECK(!fd.auto_close); |
214 files_to_register->Share(kStatsTableSharedMemFd, fd.fd); | 219 files_to_register->Share(kStatsTableSharedMemFd, fd.fd); |
215 } | 220 } |
216 #endif | 221 #endif |
217 | 222 |
(...skipping 11 matching lines...) Expand all Loading... |
229 files_to_register.Pass(), | 234 files_to_register.Pass(), |
230 base::Bind(&ChildProcessLauncher::Context::OnChildProcessStarted, | 235 base::Bind(&ChildProcessLauncher::Context::OnChildProcessStarted, |
231 this_object, | 236 this_object, |
232 client_thread_id, | 237 client_thread_id, |
233 begin_launch_time)); | 238 begin_launch_time)); |
234 | 239 |
235 #elif defined(OS_POSIX) | 240 #elif defined(OS_POSIX) |
236 base::ProcessHandle handle = base::kNullProcessHandle; | 241 base::ProcessHandle handle = base::kNullProcessHandle; |
237 // We need to close the client end of the IPC channel to reliably detect | 242 // We need to close the client end of the IPC channel to reliably detect |
238 // child termination. | 243 // child termination. |
239 base::ScopedFD ipcfd_closer(ipcfd); | |
240 | 244 |
241 #if !defined(OS_MACOSX) | 245 #if !defined(OS_MACOSX) |
242 GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess( | 246 GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess( |
243 *cmd_line, child_process_id, files_to_register.get()); | 247 *cmd_line, child_process_id, files_to_register.get()); |
244 if (use_zygote) { | 248 if (use_zygote) { |
245 handle = ZygoteHostImpl::GetInstance()->ForkRequest( | 249 handle = ZygoteHostImpl::GetInstance()->ForkRequest( |
246 cmd_line->argv(), files_to_register.Pass(), process_type); | 250 cmd_line->argv(), files_to_register.Pass(), process_type); |
247 } else | 251 } else |
248 // Fall through to the normal posix case below when we're not zygoting. | 252 // Fall through to the normal posix case below when we're not zygoting. |
249 #endif // !defined(OS_MACOSX) | 253 #endif // !defined(OS_MACOSX) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 #endif // !defined(OS_ANDROID) | 331 #endif // !defined(OS_ANDROID) |
328 } | 332 } |
329 | 333 |
330 void Notify( | 334 void Notify( |
331 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 335 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
332 bool zygote, | 336 bool zygote, |
333 #endif | 337 #endif |
334 base::ProcessHandle handle) { | 338 base::ProcessHandle handle) { |
335 #if defined(OS_ANDROID) | 339 #if defined(OS_ANDROID) |
336 // Finally close the ipcfd | 340 // Finally close the ipcfd |
337 base::ScopedFD ipcfd_closer(ipcfd_); | 341 base::ScopedFD ipcfd_closer = ipcfd_.Pass(); |
338 #endif | 342 #endif |
339 starting_ = false; | 343 starting_ = false; |
340 process_.set_handle(handle); | 344 process_.set_handle(handle); |
341 if (!handle) | 345 if (!handle) |
342 LOG(ERROR) << "Failed to launch child process"; | 346 LOG(ERROR) << "Failed to launch child process"; |
343 | 347 |
344 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 348 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
345 zygote_ = zygote; | 349 zygote_ = zygote; |
346 #endif | 350 #endif |
347 if (client_) { | 351 if (client_) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 BrowserThread::ID client_thread_id_; | 422 BrowserThread::ID client_thread_id_; |
419 base::Process process_; | 423 base::Process process_; |
420 base::TerminationStatus termination_status_; | 424 base::TerminationStatus termination_status_; |
421 int exit_code_; | 425 int exit_code_; |
422 bool starting_; | 426 bool starting_; |
423 // Controls whether the child process should be terminated on browser | 427 // Controls whether the child process should be terminated on browser |
424 // shutdown. Default behavior is to terminate the child. | 428 // shutdown. Default behavior is to terminate the child. |
425 bool terminate_child_on_shutdown_; | 429 bool terminate_child_on_shutdown_; |
426 #if defined(OS_ANDROID) | 430 #if defined(OS_ANDROID) |
427 // The fd to close after creating the process. | 431 // The fd to close after creating the process. |
428 int ipcfd_; | 432 base::ScopedFD ipcfd_; |
429 #elif defined(OS_POSIX) && !defined(OS_MACOSX) | 433 #elif defined(OS_POSIX) && !defined(OS_MACOSX) |
430 bool zygote_; | 434 bool zygote_; |
431 #endif | 435 #endif |
432 }; | 436 }; |
433 | 437 |
434 | 438 |
435 ChildProcessLauncher::ChildProcessLauncher( | 439 ChildProcessLauncher::ChildProcessLauncher( |
436 SandboxedProcessLauncherDelegate* delegate, | 440 SandboxedProcessLauncherDelegate* delegate, |
437 base::CommandLine* cmd_line, | 441 base::CommandLine* cmd_line, |
438 int child_process_id, | 442 int child_process_id, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 GetHandle(), background)); | 519 GetHandle(), background)); |
516 } | 520 } |
517 | 521 |
518 void ChildProcessLauncher::SetTerminateChildOnShutdown( | 522 void ChildProcessLauncher::SetTerminateChildOnShutdown( |
519 bool terminate_on_shutdown) { | 523 bool terminate_on_shutdown) { |
520 if (context_.get()) | 524 if (context_.get()) |
521 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); | 525 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); |
522 } | 526 } |
523 | 527 |
524 } // namespace content | 528 } // namespace content |
OLD | NEW |