Chromium Code Reviews| Index: components/browser_watcher/window_hang_monitor_win.h |
| diff --git a/components/browser_watcher/window_hang_monitor_win.h b/components/browser_watcher/window_hang_monitor_win.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..52822e767a4a243055f7101ca54d946a137ec04c |
| --- /dev/null |
| +++ b/components/browser_watcher/window_hang_monitor_win.h |
| @@ -0,0 +1,101 @@ |
| +// Copyright 2015 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. |
| +#ifndef COMPONENTS_BROWSER_WATCHER_WINDOW_HANG_MONITOR_WIN_H_ |
| +#define COMPONENTS_BROWSER_WATCHER_WINDOW_HANG_MONITOR_WIN_H_ |
| + |
| +#include <windows.h> |
| + |
| +#include "base/callback_forward.h" |
| +#include "base/macros.h" |
| +#include "base/process/process.h" |
| +#include "base/strings/string16.h" |
| +#include "base/time/time.h" |
| +#include "base/timer/timer.h" |
| + |
| +namespace browser_watcher { |
| + |
| +// Monitors a window for hanging by periodically sending it a WM_NULL message |
| +// and timing the response. |
| +class WindowHangMonitor { |
| + public: |
| + enum WindowEvent { |
| + WINDOW_HUNG, |
| + WINDOW_VANISHED, |
| + }; |
| + // Called when a hang is detected or when the window has gone away. |
| + // Called precisely zero or one time(s). |
| + typedef base::Callback<void(WindowEvent)> WindowEventCallback; |
| + |
| + // Initialize the monitor with an event callback. |
| + explicit WindowHangMonitor(const WindowEventCallback& callback); |
| + ~WindowHangMonitor(); |
| + |
| + // Initializes the watcher to monitor the window answering to |window_name|. |
| + // Returns true on success. |
| + bool Initialize(const base::string16& window_name); |
| + |
| + // Testing accessors. |
| + bool IsIdleForTesting() const { return !timer_.IsRunning(); } |
| + void SetPingIntervalForTesting(base::TimeDelta ping_interval); |
| + void SetHangTimeoutForTesting(base::TimeDelta hang_timeout); |
| + |
| + HWND window() const { return window_; } |
| + const base::Process& window_process() const { return window_process_; } |
| + |
| + private: |
| + struct OutstandingPing { |
| + WindowHangMonitor* monitor; |
| + }; |
| + |
| + static void CALLBACK |
| + OnPongReceived(HWND window, UINT msg, ULONG_PTR data, LRESULT lresult); |
| + |
| + // Checks that |window_| is still valid, and sends it a ping. |
| + // Issues a |WINDOW_VANISHED| callback if the window's no longer valid. |
| + // Schedules OnHangTimeout in case of success. |
| + // Returns true on success, false if the window is no longer valid or other |
| + // failure. |
| + bool MaybeSendPing(); |
| + |
| + // Runs after a |hang_timeout_| delay after sending a ping. Checks whether |
| + // a pong was received. Either issues a callback or schedules OnRetryTimeout. |
| + void OnHangTimeout(); |
| + |
| + // Runs periodically at |ping_interval_| interval, as long as the window is |
| + // still valid and not hung. |
| + void OnRetryTimeout(); |
| + |
| + // Invoked on significant window events. |
| + WindowEventCallback callback_; |
| + |
| + // The name of the (message) window to monitor. |
| + base::string16 window_name_; |
| + |
| + // The monitored window handle. |
| + HWND window_; |
| + |
| + // The process that owned |window_| when Initialize was called. |
| + base::Process window_process_; |
| + |
| + // The time the last message was sent. |
| + base::Time last_ping_; |
| + |
| + // The ping interval, must be larger than |hang_timeout_|. |
| + base::TimeDelta ping_interval_; |
| + // The time after which |window_| is assumed hung. |
|
erikwright (departed)
2015/03/25 20:06:58
blank line preceding, for consistency
Sigurður Ásgeirsson
2015/03/25 20:41:17
Done.
|
| + base::TimeDelta hang_timeout_; |
| + |
| + // The timer used to schedule polls. |
| + base::Timer timer_; |
| + |
| + // Non-null when there is an outstanding ping. |
| + // This is intentionally leaked when a hang is detected. |
| + OutstandingPing* outstanding_ping_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(WindowHangMonitor); |
| +}; |
| + |
| +} // namespace browser_watcher |
| + |
| +#endif // COMPONENTS_BROWSER_WATCHER_WINDOW_HANG_MONITOR_WIN_H_ |