From 1489b9dde4ad579518d8f5e27ff87399a8a994cb Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Thu, 6 Sep 2018 17:32:01 +0200 Subject: [PATCH] Windows: Fix DCHECKs during shutdown with multi-threaded message loop mode (issue #2362) --- libcef/common/main_delegate.cc | 14 ++++++++++++-- patch/patch.cfg | 4 ++++ patch/patches/message_loop.patch | 27 +++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index c75aa5737..d538c1b76 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -13,6 +13,7 @@ #include "libcef/renderer/content_renderer_client.h" #include "libcef/utility/content_utility_client.h" +#include "base/at_exit.h" #include "base/base_switches.h" #include "base/command_line.h" #include "base/files/file_path.h" @@ -281,6 +282,14 @@ class CefUIThread : public base::Thread { browser_runner_->Shutdown(); browser_runner_.reset(NULL); + // Release MessagePump resources registered with the AtExitManager. + base::MessageLoop* ml = const_cast(message_loop()); + base::MessageLoopCurrent::UnbindFromCurrentThreadInternal(ml); + ml->ReleasePump(); + + // Run exit callbacks on the UI thread to avoid sequence check failures. + base::AtExitManager::ProcessCallbacksNow(); + #if defined(OS_WIN) // Closes the COM library on the current thread. CoInitialize must // be balanced by a corresponding call to CoUninitialize. @@ -635,13 +644,14 @@ void CefMainDelegate::ShutdownBrowser() { browser_runner_->Shutdown(); browser_runner_.reset(NULL); } + + message_loop_.reset(); + if (ui_thread_.get()) { // Blocks until the thread has stopped. ui_thread_->Stop(); ui_thread_.reset(); } - - message_loop_.reset(); } void CefMainDelegate::InitializeResourceBundle() { diff --git a/patch/patch.cfg b/patch/patch.cfg index 6f2b811b9..a8672499a 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -47,6 +47,10 @@ patches = [ # # Revert change that removes MessageLoopForUI constructor. # https://chromium-review.googlesource.com/751322 + # + # Add MessageLoop::ReleasePump to fix crashes during shutdown with multi- + # threaded message loop mode. + # https://bitbucket.org/chromiumembedded/cef/issues/2362 'name': 'message_loop', }, { diff --git a/patch/patches/message_loop.patch b/patch/patches/message_loop.patch index cbff404d2..cc657a494 100644 --- a/patch/patches/message_loop.patch +++ b/patch/patches/message_loop.patch @@ -13,10 +13,20 @@ index ff55a15ce0f0..30a903dffcdc 100644 MessageLoopCurrentForUI MessageLoopForUI::current() { return MessageLoopCurrentForUI::Get(); diff --git base/message_loop/message_loop.h base/message_loop/message_loop.h -index dae6c35eab00..adbd6e72c7a3 100644 +index dae6c35eab00..f1b59fccd4c0 100644 --- base/message_loop/message_loop.h +++ base/message_loop/message_loop.h -@@ -366,6 +366,7 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate, +@@ -197,6 +197,9 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate, + // Runs the specified PendingTask. + void RunTask(PendingTask* pending_task); + ++ // Called from Thread::CleanUp() to release resources. ++ void ReleasePump() { pump_ = nullptr; } ++ + //---------------------------------------------------------------------------- + protected: + std::unique_ptr pump_; +@@ -366,6 +369,7 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate, class BASE_EXPORT MessageLoopForUI : public MessageLoop { public: explicit MessageLoopForUI(Type type = TYPE_UI); @@ -24,6 +34,19 @@ index dae6c35eab00..adbd6e72c7a3 100644 // TODO(gab): Mass migrate callers to MessageLoopCurrentForUI::Get()/IsSet(). static MessageLoopCurrentForUI current(); +diff --git base/message_loop/message_loop_current.cc base/message_loop/message_loop_current.cc +index ece6b92ca3a3..3925cdd3ad7f 100644 +--- base/message_loop/message_loop_current.cc ++++ base/message_loop/message_loop_current.cc +@@ -43,6 +43,8 @@ void MessageLoopCurrent::AddDestructionObserver( + + void MessageLoopCurrent::RemoveDestructionObserver( + DestructionObserver* destruction_observer) { ++ if (!current_) ++ return; + DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_); + current_->destruction_observers_.RemoveObserver(destruction_observer); + } diff --git base/message_loop/message_loop_current.h base/message_loop/message_loop_current.h index d623cbc7f7b2..04d83792f98d 100644 --- base/message_loop/message_loop_current.h