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); |