Index: chrome/browser/hang_monitor/hung_window_detector.cc |
diff --git a/chrome/browser/hang_monitor/hung_window_detector.cc b/chrome/browser/hang_monitor/hung_window_detector.cc |
deleted file mode 100644 |
index 47e253f0fde44d8b468bea2bc057024146540d7a..0000000000000000000000000000000000000000 |
--- a/chrome/browser/hang_monitor/hung_window_detector.cc |
+++ /dev/null |
@@ -1,160 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/hang_monitor/hung_window_detector.h" |
- |
-#include <windows.h> |
-#include <atlbase.h> |
- |
-#include "base/logging.h" |
-#include "base/win/win_util.h" |
-#include "chrome/browser/hang_monitor/hang_crash_dump_win.h" |
-#include "content/public/common/result_codes.h" |
- |
-const wchar_t HungWindowDetector::kHungChildWindowTimeout[] = |
- L"Chrome_HungChildWindowTimeout"; |
- |
-HungWindowDetector::HungWindowDetector(HungWindowNotification* notification) |
- : notification_(notification), |
- top_level_window_(NULL), |
- message_response_timeout_(0), |
- enumerating_(false) { |
- DCHECK(NULL != notification_); |
-} |
-// NOTE: It is the caller's responsibility to make sure that |
-// callbacks on this object have been stopped before |
-// destroying this object |
-HungWindowDetector::~HungWindowDetector() { |
-} |
- |
-bool HungWindowDetector::Initialize(HWND top_level_window, |
- int message_response_timeout) { |
- if (NULL == notification_) { |
- return false; |
- } |
- if (NULL == top_level_window) { |
- return false; |
- } |
- // It is OK to call Initialize on this object repeatedly |
- // with different top lebel HWNDs and timeout values each time. |
- // And we do not need a lock for this because we are just |
- // swapping DWORDs. |
- top_level_window_ = top_level_window; |
- message_response_timeout_ = message_response_timeout; |
- return true; |
-} |
- |
-void HungWindowDetector::OnTick() { |
- do { |
- base::AutoLock lock(hang_detection_lock_); |
- // If we already are checking for hung windows on another thread, |
- // don't do this again. |
- if (enumerating_) { |
- return; |
- } |
- enumerating_ = true; |
- } while (false); // To scope the AutoLock |
- |
- EnumChildWindows(top_level_window_, ChildWndEnumProc, |
- reinterpret_cast<LPARAM>(this)); |
- |
- // The window shouldn't be disabled unless we're showing a modal dialog. |
- // If we're not, then reenable the window. |
- if (!::IsWindowEnabled(top_level_window_) && |
- !::GetWindow(top_level_window_, GW_ENABLEDPOPUP)) { |
- ::EnableWindow(top_level_window_, TRUE); |
- } |
- |
- enumerating_ = false; |
-} |
- |
-bool HungWindowDetector::CheckChildWindow(HWND child_window) { |
- // It can happen that the window is DOA. It specifically happens |
- // when we have just killed a plugin process and the enum is still |
- // enumerating windows from that process. |
- if (!IsWindow(child_window)) { |
- return true; |
- } |
- |
- DWORD top_level_window_thread_id = |
- GetWindowThreadProcessId(top_level_window_, NULL); |
- |
- DWORD child_window_process_id = 0; |
- DWORD child_window_thread_id = |
- GetWindowThreadProcessId(child_window, &child_window_process_id); |
- bool continue_hang_detection = true; |
- |
- if (top_level_window_thread_id != child_window_thread_id) { |
- // The message timeout for a child window starts of with a default |
- // value specified by the message_response_timeout_ member. It is |
- // tracked by a property on the child window. |
- int child_window_message_timeout = base::win::HandleToUint32( |
- GetProp(child_window, kHungChildWindowTimeout)); |
- if (!child_window_message_timeout) { |
- child_window_message_timeout = message_response_timeout_; |
- } |
- |
- DWORD_PTR result = 0; |
- if (0 == SendMessageTimeout(child_window, |
- WM_NULL, |
- 0, |
- 0, |
- SMTO_BLOCK, |
- child_window_message_timeout, |
- &result)) { |
- HungWindowNotification::ActionOnHungWindow action = |
- HungWindowNotification::HUNG_WINDOW_IGNORE; |
-#pragma warning(disable:4312) |
- SetProp(child_window, kHungChildWindowTimeout, |
- reinterpret_cast<HANDLE>(child_window_message_timeout)); |
-#pragma warning(default:4312) |
- continue_hang_detection = |
- notification_->OnHungWindowDetected(child_window, top_level_window_, |
- &action); |
- // Make sure this window still a child of our top-level parent |
- if (!IsChild(top_level_window_, child_window)) { |
- return continue_hang_detection; |
- } |
- |
- if (action == HungWindowNotification::HUNG_WINDOW_TERMINATE_PROCESS) { |
- RemoveProp(child_window, kHungChildWindowTimeout); |
- CHandle child_process(OpenProcess(PROCESS_ALL_ACCESS, |
- FALSE, |
- child_window_process_id)); |
- |
- if (NULL == child_process.m_h) { |
- return continue_hang_detection; |
- } |
- // Before swinging the axe, do some sanity checks to make |
- // sure this window still belongs to the same process |
- DWORD process_id_check = 0; |
- GetWindowThreadProcessId(child_window, &process_id_check); |
- if (process_id_check != child_window_process_id) { |
- return continue_hang_detection; |
- } |
- |
- // Before terminating the process we try collecting a dump. Which |
- // a transient thread in the child process will do for us. |
- CrashDumpAndTerminateHungChildProcess(child_process); |
- child_process.Close(); |
- } |
- } else { |
- RemoveProp(child_window, kHungChildWindowTimeout); |
- } |
- } |
- |
- return continue_hang_detection; |
-} |
- |
-BOOL CALLBACK HungWindowDetector::ChildWndEnumProc(HWND child_window, |
- LPARAM param) { |
- HungWindowDetector* detector_instance = |
- reinterpret_cast<HungWindowDetector*>(param); |
- if (NULL == detector_instance) { |
- NOTREACHED(); |
- return FALSE; |
- } |
- |
- return detector_instance->CheckChildWindow(child_window); |
-} |