gpu_watchdog_thread.h revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_GPU_GPU_WATCHDOG_THREAD_H_
6#define CONTENT_GPU_GPU_WATCHDOG_THREAD_H_
7
8#include "base/memory/ref_counted.h"
9#include "base/memory/weak_ptr.h"
10#include "base/message_loop.h"
11#include "base/threading/thread.h"
12#include "base/time/time.h"
13#include "content/common/gpu/gpu_watchdog.h"
14
15namespace content {
16
17// A thread that intermitently sends tasks to a group of watched message loops
18// and deliberately crashes if one of them does not respond after a timeout.
19class GpuWatchdogThread : public base::Thread,
20                          public GpuWatchdog,
21                          public base::RefCountedThreadSafe<GpuWatchdogThread> {
22 public:
23  explicit GpuWatchdogThread(int timeout);
24
25  // Accessible on watched thread but only modified by watchdog thread.
26  bool armed() const { return armed_; }
27  void PostAcknowledge();
28
29  // Implement GpuWatchdog.
30  virtual void CheckArmed() OVERRIDE;
31
32 protected:
33  virtual void Init() OVERRIDE;
34  virtual void CleanUp() OVERRIDE;
35
36 private:
37  friend class base::RefCountedThreadSafe<GpuWatchdogThread>;
38
39  // An object of this type intercepts the reception and completion of all tasks
40  // on the watched thread and checks whether the watchdog is armed.
41  class GpuWatchdogTaskObserver : public base::MessageLoop::TaskObserver {
42   public:
43    explicit GpuWatchdogTaskObserver(GpuWatchdogThread* watchdog);
44    virtual ~GpuWatchdogTaskObserver();
45
46    // Implements MessageLoop::TaskObserver.
47    virtual void WillProcessTask(
48        const base::PendingTask& pending_task) OVERRIDE;
49    virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE;
50
51   private:
52    GpuWatchdogThread* watchdog_;
53  };
54
55  virtual ~GpuWatchdogThread();
56
57  void OnAcknowledge();
58  void OnCheck(bool after_suspend);
59  void DeliberatelyTerminateToRecoverFromHang();
60
61#if defined(OS_WIN)
62  base::TimeDelta GetWatchedThreadTime();
63#endif
64
65  base::MessageLoop* watched_message_loop_;
66  base::TimeDelta timeout_;
67  volatile bool armed_;
68  GpuWatchdogTaskObserver task_observer_;
69
70#if defined(OS_WIN)
71  void* watched_thread_handle_;
72  base::TimeDelta arm_cpu_time_;
73#endif
74
75  // Time after which it's assumed that the computer has been suspended since
76  // the task was posted.
77  base::Time suspension_timeout_;
78
79  base::WeakPtrFactory<GpuWatchdogThread> weak_factory_;
80
81  DISALLOW_COPY_AND_ASSIGN(GpuWatchdogThread);
82};
83
84}  // namespace content
85
86#endif  // CONTENT_GPU_GPU_WATCHDOG_THREAD_H_
87