| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/child_process_launcher.h" | 5 #include "chrome/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/lock.h" |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/scoped_ptr.h" | 12 #include "base/scoped_ptr.h" |
| 12 #include "base/thread.h" | 13 #include "base/thread.h" |
| 13 #include "chrome/browser/chrome_thread.h" | 14 #include "chrome/browser/chrome_thread.h" |
| 14 #include "chrome/common/chrome_descriptors.h" | 15 #include "chrome/common/chrome_descriptors.h" |
| 15 #include "chrome/common/chrome_switches.h" | 16 #include "chrome/common/chrome_switches.h" |
| 16 #include "chrome/common/process_watcher.h" | 17 #include "chrome/common/process_watcher.h" |
| 17 #include "chrome/common/result_codes.h" | 18 #include "chrome/common/result_codes.h" |
| 18 | 19 |
| 19 #if defined(OS_WIN) | 20 #if defined(OS_WIN) |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 } | 155 } |
| 155 if (is_renderer) { | 156 if (is_renderer) { |
| 156 const int sandbox_fd = | 157 const int sandbox_fd = |
| 157 Singleton<RenderSandboxHostLinux>()->GetRendererSocket(); | 158 Singleton<RenderSandboxHostLinux>()->GetRendererSocket(); |
| 158 fds_to_map.push_back(std::make_pair( | 159 fds_to_map.push_back(std::make_pair( |
| 159 sandbox_fd, | 160 sandbox_fd, |
| 160 kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); | 161 kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); |
| 161 } | 162 } |
| 162 #endif // defined(OS_LINUX) | 163 #endif // defined(OS_LINUX) |
| 163 | 164 |
| 164 // Actually launch the app. | 165 bool launched = false; |
| 165 bool launched; | |
| 166 #if defined(OS_MACOSX) | 166 #if defined(OS_MACOSX) |
| 167 task_t child_task; | 167 // It is possible for the child process to die immediately after |
| 168 launched = base::LaunchAppAndGetTask( | 168 // launching. To prevent leaking MachBroker map entries in this case, |
| 169 cmd_line->argv(), env, fds_to_map, false, &child_task, &handle); | 169 // lock around all of LaunchApp(). If the child dies, the death |
| 170 if (launched && child_task != MACH_PORT_NULL) { | 170 // notification will be processed by the MachBroker after the call to |
| 171 MachBroker::instance()->RegisterPid( | 171 // AddPlaceholderForPid(), enabling proper cleanup. |
| 172 handle, | 172 { // begin scope for AutoLock |
| 173 MachBroker::MachInfo().SetTask(child_task)); | 173 MachBroker* broker = MachBroker::instance(); |
| 174 } | 174 AutoLock lock(broker->GetLock()); |
| 175 #else | 175 |
| 176 launched = base::LaunchApp(cmd_line->argv(), env, fds_to_map, | 176 // This call to |PrepareForFork()| will start the MachBroker listener |
| 177 /* wait= */false, &handle); | 177 // thread, if it is not already running. Therefore the browser process |
| 178 // will be listening for Mach IPC before LaunchApp() is called. |
| 179 broker->PrepareForFork(); |
| 180 #endif |
| 181 // Actually launch the app. |
| 182 launched = base::LaunchApp(cmd_line->argv(), env, fds_to_map, |
| 183 /* wait= */false, &handle); |
| 184 #if defined(OS_MACOSX) |
| 185 if (launched) |
| 186 broker->AddPlaceholderForPid(handle); |
| 187 } // end scope for AutoLock |
| 178 #endif | 188 #endif |
| 179 if (!launched) | 189 if (!launched) |
| 180 handle = base::kNullProcessHandle; | 190 handle = base::kNullProcessHandle; |
| 181 } | 191 } |
| 182 #endif // else defined(OS_POSIX) | 192 #endif // else defined(OS_POSIX) |
| 183 | 193 |
| 184 ChromeThread::PostTask( | 194 ChromeThread::PostTask( |
| 185 client_thread_id_, FROM_HERE, | 195 client_thread_id_, FROM_HERE, |
| 186 NewRunnableMethod( | 196 NewRunnableMethod( |
| 187 this, | 197 this, |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 if (child_exited) | 328 if (child_exited) |
| 319 context_->process_.Close(); | 329 context_->process_.Close(); |
| 320 | 330 |
| 321 return did_crash; | 331 return did_crash; |
| 322 } | 332 } |
| 323 | 333 |
| 324 void ChildProcessLauncher::SetProcessBackgrounded(bool background) { | 334 void ChildProcessLauncher::SetProcessBackgrounded(bool background) { |
| 325 DCHECK(!context_->starting_); | 335 DCHECK(!context_->starting_); |
| 326 context_->process_.SetProcessBackgrounded(background); | 336 context_->process_.SetProcessBackgrounded(background); |
| 327 } | 337 } |
| OLD | NEW |