Chromium Code Reviews| Index: content/child/child_process.cc |
| diff --git a/content/child/child_process.cc b/content/child/child_process.cc |
| index 2763ee03cffdb0b12d5934091b9c31f7bad6ff39..f3012ad303c7cf25419b7e0a3fc08890c21eced7 100644 |
| --- a/content/child/child_process.cc |
| +++ b/content/child/child_process.cc |
| @@ -6,6 +6,8 @@ |
| #include <string.h> |
| +#include "base/at_exit.h" |
| +#include "base/command_line.h" |
| #include "base/lazy_instance.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/metrics/statistics_recorder.h" |
| @@ -17,6 +19,7 @@ |
| #include "base/threading/thread_local.h" |
| #include "build/build_config.h" |
| #include "content/child/child_thread_impl.h" |
| +#include "content/public/common/content_switches.h" |
| #if defined(OS_ANDROID) |
| #include "base/debug/debugger.h" |
| @@ -67,11 +70,34 @@ ChildProcess::~ChildProcess() { |
| // notice shutdown before the render process begins waiting for them to exit. |
| shutdown_event_.Signal(); |
| - // Kill the main thread object before nulling child_process, since |
| - // destruction code might depend on it. |
| if (main_thread_) { // null in unittests. |
| - main_thread_->Shutdown(); |
| - main_thread_.reset(); |
| + if (main_thread_->IsRenderThread()) { |
|
jochen (gone - plz use gerrit)
2017/01/11 12:26:25
why not do this work in RenderThreadImpl::Shutdown
Torne
2017/01/11 12:50:58
If there's a good way to do that it seems like a g
haraken
2017/01/11 12:52:25
Because we need to call main_thread_.release(). It
jochen (gone - plz use gerrit)
2017/01/11 12:52:59
Shutdown() could return an enum indicating what to
|
| + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kSingleProcess)) { |
| + // In a multi-process mode, we immediately exit the renderer. |
| + // Historically we had a graceful shutdown sequence here but it was |
| + // 1) a waste of performance and 2) a source of lots of complicated |
| + // crashes caused by shutdown ordering. Immediate exit eliminates |
| + // those problems. |
| + _exit(0); |
| + } else { |
| + // In a single-process mode, we cannot call _exit(0) here because |
| + // it will exit the process before the browser side is ready to exit. |
| + // On the other hand, we cannot call main_thread_.reset() because |
| + // it is unsafe to destruct main_thread_ without shutting down the |
| + // main_thread_ (we no longer have the shutdown sequence). Hence we |
| + // leak main_thread_. |
| + // |
| + // Then we need to disable at-exit callbacks because some of the |
| + // at-exit callbacks are expected to run after main_thread_ has been |
| + // destructed. |
| + base::AtExitManager::DisableAllAtExitManagers(); |
|
jochen (gone - plz use gerrit)
2017/01/11 12:26:25
won't that disable at exit managers for stuff that
Torne
2017/01/11 12:50:58
Yes. The assumption is that as the only shipping c
haraken
2017/01/11 12:52:25
You're right. Ideally we should stop calling at-ex
|
| + main_thread_.release(); |
| + } |
| + } else { |
| + main_thread_->Shutdown(); |
| + main_thread_.reset(); |
| + } |
| } |
| g_lazy_tls.Pointer()->Set(NULL); |