| 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 |