Commit b4807c2e authored by OlivierLi's avatar OlivierLi Committed by Commit Bot

Activate hang watching on the browser UI thread.

This also introduces the first use of HangWatchScopeDisabled to ignore
cases where tasks are not processed because an nested loop is processing
only native events.

Bug: 1034046
Change-Id: I5f425226d20d3c0f75038f0ea234ae7308bcbc9a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2340076Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Commit-Queue: François Doray <fdoray@chromium.org>
Auto-Submit: Oliver Li <olivierli@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798769}
parent 78d7ee38
...@@ -33,6 +33,8 @@ constexpr base::Feature kEnableHangWatcher{"EnableHangWatcher", ...@@ -33,6 +33,8 @@ constexpr base::Feature kEnableHangWatcher{"EnableHangWatcher",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
constexpr base::FeatureParam<bool> kHangWatchIOThread{ constexpr base::FeatureParam<bool> kHangWatchIOThread{
&kEnableHangWatcher, "hang_watch_io_thread", false}; &kEnableHangWatcher, "hang_watch_io_thread", false};
constexpr base::FeatureParam<bool> kHangWatchUIThread{
&kEnableHangWatcher, "hang_watch_ui_thread", false};
constexpr base::FeatureParam<bool> kHangWatchThreadPool{ constexpr base::FeatureParam<bool> kHangWatchThreadPool{
&kEnableHangWatcher, "hang_watch_threadpool", false}; &kEnableHangWatcher, "hang_watch_threadpool", false};
...@@ -44,6 +46,7 @@ HangWatcher* g_instance = nullptr; ...@@ -44,6 +46,7 @@ HangWatcher* g_instance = nullptr;
std::atomic<bool> g_use_hang_watcher{false}; std::atomic<bool> g_use_hang_watcher{false};
std::atomic<bool> g_hang_watch_workers{false}; std::atomic<bool> g_hang_watch_workers{false};
std::atomic<bool> g_hang_watch_io_thread{false}; std::atomic<bool> g_hang_watch_io_thread{false};
std::atomic<bool> g_hang_watch_ui_thread{false};
} }
constexpr const char* kThreadName = "HangWatcher"; constexpr const char* kThreadName = "HangWatcher";
...@@ -192,6 +195,7 @@ void HangWatcher::InitializeOnMainThread() { ...@@ -192,6 +195,7 @@ void HangWatcher::InitializeOnMainThread() {
DCHECK(!g_use_hang_watcher); DCHECK(!g_use_hang_watcher);
DCHECK(!g_hang_watch_workers); DCHECK(!g_hang_watch_workers);
DCHECK(!g_hang_watch_io_thread); DCHECK(!g_hang_watch_io_thread);
DCHECK(!g_hang_watch_ui_thread);
g_use_hang_watcher.store(base::FeatureList::IsEnabled(kEnableHangWatcher), g_use_hang_watcher.store(base::FeatureList::IsEnabled(kEnableHangWatcher),
std::memory_order_relaxed); std::memory_order_relaxed);
...@@ -203,6 +207,8 @@ void HangWatcher::InitializeOnMainThread() { ...@@ -203,6 +207,8 @@ void HangWatcher::InitializeOnMainThread() {
std::memory_order_relaxed); std::memory_order_relaxed);
g_hang_watch_io_thread.store(kHangWatchIOThread.Get(), g_hang_watch_io_thread.store(kHangWatchIOThread.Get(),
std::memory_order_relaxed); std::memory_order_relaxed);
g_hang_watch_ui_thread.store(kHangWatchUIThread.Get(),
std::memory_order_relaxed);
} }
} }
...@@ -220,6 +226,10 @@ bool HangWatcher::IsIOThreadHangWatchingEnabled() { ...@@ -220,6 +226,10 @@ bool HangWatcher::IsIOThreadHangWatchingEnabled() {
return g_hang_watch_io_thread.load(std::memory_order_relaxed); return g_hang_watch_io_thread.load(std::memory_order_relaxed);
} }
bool HangWatcher::IsUIThreadHangWatchingEnabled() {
return g_hang_watch_io_thread.load(std::memory_order_relaxed);
}
HangWatcher::HangWatcher() HangWatcher::HangWatcher()
: monitor_period_(kMonitoringPeriod), : monitor_period_(kMonitoringPeriod),
should_monitor_(WaitableEvent::ResetPolicy::AUTOMATIC), should_monitor_(WaitableEvent::ResetPolicy::AUTOMATIC),
......
...@@ -157,6 +157,7 @@ class BASE_EXPORT HangWatcher : public DelegateSimpleThread::Delegate { ...@@ -157,6 +157,7 @@ class BASE_EXPORT HangWatcher : public DelegateSimpleThread::Delegate {
static bool IsEnabled(); static bool IsEnabled();
static bool IsThreadPoolHangWatchingEnabled(); static bool IsThreadPoolHangWatchingEnabled();
static bool IsIOThreadHangWatchingEnabled(); static bool IsIOThreadHangWatchingEnabled();
static bool IsUIThreadHangWatchingEnabled();
// Sets up the calling thread to be monitored for threads. Returns a // Sets up the calling thread to be monitored for threads. Returns a
// ScopedClosureRunner that unregisters the thread. This closure has to be // ScopedClosureRunner that unregisters the thread. This closure has to be
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "base/threading/hang_watcher.h"
#include "base/threading/scoped_thread_priority.h" #include "base/threading/scoped_thread_priority.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/win/win_util.h" #include "base/win/win_util.h"
...@@ -516,6 +517,10 @@ bool AuthenticateUserNew(gfx::NativeWindow window, ...@@ -516,6 +517,10 @@ bool AuthenticateUserNew(gfx::NativeWindow window,
cui.pszCaptionText = product_name.c_str(); cui.pszCaptionText = product_name.c_str();
cui.hbmBanner = nullptr; cui.hbmBanner = nullptr;
// Disable hang watching until the end of the function since the user can take
// unbounded time to answer the password prompt. (http://crbug.com/806174)
base::HangWatchScopeDisabled disabler;
CredentialBufferValidator validator; CredentialBufferValidator validator;
DWORD err = 0; DWORD err = 0;
......
...@@ -524,6 +524,15 @@ BrowserMainLoop::BrowserMainLoop( ...@@ -524,6 +524,15 @@ BrowserMainLoop::BrowserMainLoop(
<< "ThreadPool must be halted before kicking off content."; << "ThreadPool must be halted before kicking off content.";
g_current_browser_main_loop = this; g_current_browser_main_loop = this;
// Register the UI thread for hang watching before it starts running and set
// up a closure to automatically unregister when |this| is destroyed. This
// works since the UI thread running the message loop is the main thread and
// that makes it the same as the current one.
if (base::HangWatcher::IsUIThreadHangWatchingEnabled()) {
unregister_thread_closure_ =
base::HangWatcher::GetInstance()->RegisterThread();
}
if (GetContentClient()->browser()->ShouldCreateThreadPool()) { if (GetContentClient()->browser()->ShouldCreateThreadPool()) {
DCHECK(base::ThreadPoolInstance::Get()); DCHECK(base::ThreadPoolInstance::Get());
} }
......
...@@ -293,7 +293,8 @@ class CONTENT_EXPORT BrowserMainLoop { ...@@ -293,7 +293,8 @@ class CONTENT_EXPORT BrowserMainLoop {
base::Optional<base::ThreadPoolInstance::ScopedBestEffortExecutionFence> base::Optional<base::ThreadPoolInstance::ScopedBestEffortExecutionFence>
scoped_best_effort_execution_fence_; scoped_best_effort_execution_fence_;
// Members initialized in |MainMessageLoopStart()| --------------------------- // Unregister UI thread from hang watching on destruction.
base::ScopedClosureRunner unregister_thread_closure_;
// Members initialized in |PostMainMessageLoopStart()| ----------------------- // Members initialized in |PostMainMessageLoopStart()| -----------------------
std::unique_ptr<BrowserProcessSubThread> io_thread_; std::unique_ptr<BrowserProcessSubThread> io_thread_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment