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 |