Chromium Code Reviews| 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 ipcfd, | 102 ipcfd, |
| 103 #endif | 103 #endif |
| 104 cmd_line)); | 104 cmd_line)); |
| 105 } | 105 } |
| 106 | 106 |
| 107 #if defined(OS_ANDROID) | 107 #if defined(OS_ANDROID) |
| 108 static void OnSandboxedProcessStarted( | 108 static void OnSandboxedProcessStarted( |
| 109 // |this_object| is NOT thread safe. Only use it to post a task back. | 109 // |this_object| is NOT thread safe. Only use it to post a task back. |
| 110 scoped_refptr<Context> this_object, | 110 scoped_refptr<Context> this_object, |
| 111 BrowserThread::ID client_thread_id, | 111 BrowserThread::ID client_thread_id, |
| 112 const content::FDInfoList& registered_files, | |
| 112 base::ProcessHandle handle) { | 113 base::ProcessHandle handle) { |
| 113 if (BrowserThread::CurrentlyOn(client_thread_id)) { | 114 if (BrowserThread::CurrentlyOn(client_thread_id)) { |
| 114 // This is always invoked on the UI thread which is commonly the | 115 // This is always invoked on the UI thread which is commonly the |
| 115 // |client_thread_id| so we can shortcut one PostTask. | 116 // |client_thread_id| so we can shortcut one PostTask. |
| 116 this_object->Notify(handle); | 117 this_object->Notify(registered_files, handle); |
| 117 } else { | 118 } else { |
| 118 BrowserThread::PostTask( | 119 BrowserThread::PostTask( |
| 119 client_thread_id, FROM_HERE, | 120 client_thread_id, FROM_HERE, |
| 120 base::Bind( | 121 base::Bind( |
| 121 &ChildProcessLauncher::Context::Notify, | 122 &ChildProcessLauncher::Context::Notify, |
| 122 this_object, | 123 this_object, |
| 124 registered_files, | |
| 123 handle)); | 125 handle)); |
| 124 } | 126 } |
| 125 } | 127 } |
| 126 #endif | 128 #endif |
| 127 | 129 |
| 128 void ResetClient() { | 130 void ResetClient() { |
| 129 // No need for locking as this function gets called on the same thread that | 131 // No need for locking as this function gets called on the same thread that |
| 130 // client_ would be used. | 132 // client_ would be used. |
| 131 CHECK(BrowserThread::CurrentlyOn(client_thread_id_)); | 133 CHECK(BrowserThread::CurrentlyOn(client_thread_id_)); |
| 132 client_ = NULL; | 134 client_ = NULL; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 159 #endif | 161 #endif |
| 160 CommandLine* cmd_line) { | 162 CommandLine* cmd_line) { |
| 161 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); | 163 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); |
| 162 | 164 |
| 163 #if defined(OS_WIN) | 165 #if defined(OS_WIN) |
| 164 base::ProcessHandle handle = sandbox::StartProcessWithAccess( | 166 base::ProcessHandle handle = sandbox::StartProcessWithAccess( |
| 165 cmd_line, exposed_dir); | 167 cmd_line, exposed_dir); |
| 166 #elif defined(OS_ANDROID) | 168 #elif defined(OS_ANDROID) |
| 167 std::string process_type = | 169 std::string process_type = |
| 168 cmd_line->GetSwitchValueASCII(switches::kProcessType); | 170 cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 169 std::vector<content::FileDescriptorInfo> files_to_register; | 171 content::FDInfoList files_to_register; |
| 170 files_to_register.push_back( | 172 files_to_register.push_back( |
| 171 content::FileDescriptorInfo(kPrimaryIPCChannel, | 173 content::FileDescriptorInfo(kPrimaryIPCChannel, |
| 172 base::FileDescriptor(ipcfd, false))); | 174 base::FileDescriptor(ipcfd, false))); |
| 173 | 175 |
| 174 content::GetContentClient()->browser()-> | 176 content::GetContentClient()->browser()-> |
| 175 GetAdditionalMappedFilesForChildProcess(*cmd_line, &files_to_register); | 177 GetAdditionalMappedFilesForChildProcess(*cmd_line, &files_to_register); |
| 176 | 178 |
| 177 content::StartSandboxedProcess(cmd_line->argv(), files_to_register, | 179 content::StartSandboxedProcess(cmd_line->argv(), files_to_register, |
| 178 base::Bind(&ChildProcessLauncher::Context::OnSandboxedProcessStarted, | 180 base::Bind(&ChildProcessLauncher::Context::OnSandboxedProcessStarted, |
| 179 this_object, client_thread_id)); | 181 this_object, client_thread_id, files_to_register)); |
| 180 | 182 |
| 181 #elif defined(OS_POSIX) | 183 #elif defined(OS_POSIX) |
| 182 base::ProcessHandle handle = base::kNullProcessHandle; | 184 base::ProcessHandle handle = base::kNullProcessHandle; |
| 183 // We need to close the client end of the IPC channel to reliably detect | 185 // We need to close the client end of the IPC channel to reliably detect |
| 184 // child termination. | 186 // child termination. |
| 185 file_util::ScopedFD ipcfd_closer(&ipcfd); | 187 file_util::ScopedFD ipcfd_closer(&ipcfd); |
| 186 | 188 |
| 187 std::string process_type = | 189 std::string process_type = |
| 188 cmd_line->GetSwitchValueASCII(switches::kProcessType); | 190 cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 189 std::vector<content::FileDescriptorInfo> files_to_register; | 191 content::FDInfoList files_to_register; |
| 190 files_to_register.push_back( | 192 files_to_register.push_back( |
| 191 content::FileDescriptorInfo(kPrimaryIPCChannel, | 193 content::FileDescriptorInfo(kPrimaryIPCChannel, |
| 192 base::FileDescriptor(ipcfd, false))); | 194 base::FileDescriptor(ipcfd, false))); |
| 193 | 195 |
| 194 #if !defined(OS_MACOSX) | 196 #if !defined(OS_MACOSX) |
| 195 content::GetContentClient()->browser()-> | 197 content::GetContentClient()->browser()-> |
| 196 GetAdditionalMappedFilesForChildProcess(*cmd_line, &files_to_register); | 198 GetAdditionalMappedFilesForChildProcess(*cmd_line, &files_to_register); |
| 197 if (use_zygote) { | 199 if (use_zygote) { |
| 198 handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(), | 200 handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(), |
| 199 files_to_register, | 201 files_to_register, |
| 200 process_type); | 202 process_type); |
| 201 } else | 203 } else |
| 202 // Fall through to the normal posix case below when we're not zygoting. | 204 // Fall through to the normal posix case below when we're not zygoting. |
| 203 #endif // !defined(OS_MACOSX) | 205 #endif // !defined(OS_MACOSX) |
| 204 { | 206 { |
| 205 // Convert FD mapping to FileHandleMappingVector | 207 // Convert FD mapping to FileHandleMappingVector |
| 206 base::FileHandleMappingVector fds_to_map; | 208 base::FileHandleMappingVector fds_to_map; |
| 207 for (std::vector<content::FileDescriptorInfo>::const_iterator | 209 for (content::FDInfoList::const_iterator i = files_to_register.begin(); |
|
jam
2012/10/19 16:39:17
nit: no need for const_iterator when iterating a v
Jay Civelli
2012/10/22 22:09:48
Done.
| |
| 208 i = files_to_register.begin(); i != files_to_register.end(); ++i) { | 210 i != files_to_register.end(); ++i) { |
| 209 const content::FileDescriptorInfo& fd_info = *i; | 211 const content::FileDescriptorInfo& fd_info = *i; |
| 210 fds_to_map.push_back(std::make_pair( | 212 fds_to_map.push_back(std::make_pair( |
| 211 fd_info.fd.fd, | 213 fd_info.fd.fd, |
| 212 fd_info.id + base::GlobalDescriptors::kBaseDescriptor)); | 214 fd_info.id + base::GlobalDescriptors::kBaseDescriptor)); |
| 213 } | 215 } |
| 214 | 216 |
| 215 #if !defined(OS_MACOSX) | 217 #if !defined(OS_MACOSX) |
| 216 if (process_type == switches::kRendererProcess) { | 218 if (process_type == switches::kRendererProcess) { |
| 217 const int sandbox_fd = | 219 const int sandbox_fd = |
| 218 RenderSandboxHostLinux::GetInstance()->GetRendererSocket(); | 220 RenderSandboxHostLinux::GetInstance()->GetRendererSocket(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 #endif // else defined(OS_POSIX) | 262 #endif // else defined(OS_POSIX) |
| 261 #if !defined(OS_ANDROID) | 263 #if !defined(OS_ANDROID) |
| 262 BrowserThread::PostTask( | 264 BrowserThread::PostTask( |
| 263 client_thread_id, FROM_HERE, | 265 client_thread_id, FROM_HERE, |
| 264 base::Bind( | 266 base::Bind( |
| 265 &Context::Notify, | 267 &Context::Notify, |
| 266 this_object.get(), | 268 this_object.get(), |
| 267 #if defined(OS_POSIX) && !defined(OS_MACOSX) | 269 #if defined(OS_POSIX) && !defined(OS_MACOSX) |
| 268 use_zygote, | 270 use_zygote, |
| 269 #endif | 271 #endif |
| 272 files_to_register, | |
| 270 handle)); | 273 handle)); |
| 271 #endif // !defined(OS_ANDROID) | 274 #endif // !defined(OS_ANDROID) |
| 272 } | 275 } |
| 273 | 276 |
| 274 void Notify( | 277 void Notify( |
| 275 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 278 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 276 bool zygote, | 279 bool zygote, |
| 277 #endif | 280 #endif |
| 281 const content::FDInfoList& registered_files, | |
| 278 base::ProcessHandle handle) { | 282 base::ProcessHandle handle) { |
| 279 #if defined(OS_ANDROID) | 283 #if defined(OS_ANDROID) |
| 280 // Finally close the ipcfd | 284 // Finally close the ipcfd |
| 281 file_util::ScopedFD ipcfd_closer(&ipcfd_); | 285 file_util::ScopedFD ipcfd_closer(&ipcfd_); |
| 282 #endif | 286 #endif |
| 283 starting_ = false; | 287 starting_ = false; |
| 284 process_.set_handle(handle); | 288 process_.set_handle(handle); |
| 285 if (!handle) | 289 if (!handle) |
| 286 LOG(ERROR) << "Failed to launch child process"; | 290 LOG(ERROR) << "Failed to launch child process"; |
| 287 | 291 |
| 288 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 292 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 289 zygote_ = zygote; | 293 zygote_ = zygote; |
| 290 #endif | 294 #endif |
| 291 if (client_) { | 295 if (client_) { |
| 292 client_->OnProcessLaunched(); | 296 client_->OnProcessLaunched(registered_files); |
| 293 } else { | 297 } else { |
| 294 Terminate(); | 298 Terminate(); |
| 295 } | 299 } |
| 296 } | 300 } |
| 297 | 301 |
| 298 void Terminate() { | 302 void Terminate() { |
| 299 if (!process_.handle()) | 303 if (!process_.handle()) |
| 300 return; | 304 return; |
| 301 | 305 |
| 302 if (!terminate_child_on_shutdown_) | 306 if (!terminate_child_on_shutdown_) |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 base::Bind( | 452 base::Bind( |
| 449 &ChildProcessLauncher::Context::SetProcessBackgrounded, | 453 &ChildProcessLauncher::Context::SetProcessBackgrounded, |
| 450 GetHandle(), background)); | 454 GetHandle(), background)); |
| 451 } | 455 } |
| 452 | 456 |
| 453 void ChildProcessLauncher::SetTerminateChildOnShutdown( | 457 void ChildProcessLauncher::SetTerminateChildOnShutdown( |
| 454 bool terminate_on_shutdown) { | 458 bool terminate_on_shutdown) { |
| 455 if (context_) | 459 if (context_) |
| 456 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); | 460 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); |
| 457 } | 461 } |
| OLD | NEW |