 Chromium Code Reviews
 Chromium Code Reviews Issue 2309153002:
  Remove RenderThreadImpl::Shutdown  (Closed)
    
  
    Issue 2309153002:
  Remove RenderThreadImpl::Shutdown  (Closed) 
  | 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); |