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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 client_->OnProcessLaunched(); | 332 client_->OnProcessLaunched(); |
333 } else { | 333 } else { |
334 Terminate(); | 334 Terminate(); |
335 } | 335 } |
336 } | 336 } |
337 | 337 |
338 void Terminate() { | 338 void Terminate() { |
339 if (!process_.handle()) | 339 if (!process_.handle()) |
340 return; | 340 return; |
341 | 341 |
342 if (!terminate_child_on_shutdown_) | |
343 return; | |
344 | |
345 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So | 342 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So |
346 // don't this on the UI/IO threads. | 343 // don't this on the UI/IO threads. |
347 BrowserThread::PostTask( | 344 BrowserThread::PostTask( |
348 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 345 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, |
349 base::Bind( | 346 base::Bind( |
350 &Context::TerminateInternal, | 347 &Context::TerminateInternal, |
351 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 348 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
352 zygote_, | 349 zygote_, |
353 #endif | 350 #endif |
354 process_.handle())); | 351 process_.handle(), |
352 !terminate_child_on_shutdown_)); | |
355 process_.set_handle(base::kNullProcessHandle); | 353 process_.set_handle(base::kNullProcessHandle); |
356 } | 354 } |
357 | 355 |
358 static void SetProcessBackgrounded(base::ProcessHandle handle, | 356 static void SetProcessBackgrounded(base::ProcessHandle handle, |
359 bool background) { | 357 bool background) { |
360 base::Process process(handle); | 358 base::Process process(handle); |
361 process.SetProcessBackgrounded(background); | 359 process.SetProcessBackgrounded(background); |
362 } | 360 } |
363 | 361 |
364 static void TerminateInternal( | 362 static void TerminateInternal( |
365 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 363 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
366 bool zygote, | 364 bool zygote, |
367 #endif | 365 #endif |
368 base::ProcessHandle handle) { | 366 base::ProcessHandle handle, |
367 bool wait_for_child_to_exit_cleanly) { | |
369 #if defined(OS_ANDROID) | 368 #if defined(OS_ANDROID) |
370 LOG(INFO) << "ChromeProcess: Stopping process with handle " << handle; | 369 LOG(INFO) << "ChromeProcess: Stopping process with handle " << handle; |
371 StopChildProcess(handle); | 370 StopChildProcess(handle); |
372 #else | 371 #else |
373 base::Process process(handle); | 372 base::Process process(handle); |
374 // Client has gone away, so just kill the process. Using exit code 0 | 373 // Client has gone away, so just kill the process. Using exit code 0 |
375 // means that UMA won't treat this as a crash. | 374 // means that UMA won't treat this as a crash. |
376 process.Terminate(RESULT_CODE_NORMAL_EXIT); | 375 if (!wait_for_child_to_exit_cleanly) |
376 process.Terminate(RESULT_CODE_NORMAL_EXIT); | |
377 | |
377 // On POSIX, we must additionally reap the child. | 378 // On POSIX, we must additionally reap the child. |
378 #if defined(OS_POSIX) | 379 #if defined(OS_POSIX) |
379 #if !defined(OS_MACOSX) | 380 #if !defined(OS_MACOSX) |
380 if (zygote) { | 381 if (zygote) { |
381 // If the renderer was created via a zygote, we have to proxy the reaping | 382 // If the renderer was created via a zygote, we have to proxy the reaping |
382 // through the zygote process. | 383 // through the zygote process. |
383 ZygoteHostImpl::GetInstance()->EnsureProcessTerminated(handle); | 384 ZygoteHostImpl::GetInstance()->EnsureProcessTerminated(handle); |
384 } else | 385 } else |
385 #endif // !OS_MACOSX | 386 #endif // !OS_MACOSX |
386 { | 387 { |
387 base::EnsureProcessTerminated(handle); | 388 if (wait_for_child_to_exit_cleanly) |
389 base::EnsureProcessGetsReaped(handle); | |
Markus (顧孟勤)
2013/07/22 22:50:13
I am really sad that we need to launch another thr
asharif1
2013/07/22 23:43:54
Note that the zygote process isn't multithreaded b
Markus (顧孟勤)
2013/07/22 23:54:27
If writing a synchronous version is possible witho
| |
390 else | |
391 base::EnsureProcessTerminated(handle); | |
388 } | 392 } |
389 #endif // OS_POSIX | 393 #endif // OS_POSIX |
390 process.Close(); | 394 process.Close(); |
391 #endif // defined(OS_ANDROID) | 395 #endif // defined(OS_ANDROID) |
392 } | 396 } |
393 | 397 |
394 Client* client_; | 398 Client* client_; |
395 BrowserThread::ID client_thread_id_; | 399 BrowserThread::ID client_thread_id_; |
396 base::Process process_; | 400 base::Process process_; |
397 base::TerminationStatus termination_status_; | 401 base::TerminationStatus termination_status_; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
493 GetHandle(), background)); | 497 GetHandle(), background)); |
494 } | 498 } |
495 | 499 |
496 void ChildProcessLauncher::SetTerminateChildOnShutdown( | 500 void ChildProcessLauncher::SetTerminateChildOnShutdown( |
497 bool terminate_on_shutdown) { | 501 bool terminate_on_shutdown) { |
498 if (context_.get()) | 502 if (context_.get()) |
499 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); | 503 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); |
500 } | 504 } |
501 | 505 |
502 } // namespace content | 506 } // namespace content |
OLD | NEW |