Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: content/gpu/gpu_watchdog_thread.cc

Issue 6463013: Add support for base::Closure in the MessageLoop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/base
Patch Set: address will's comments. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if defined(OS_WIN) 5 #if defined(OS_WIN)
6 #include <windows.h> 6 #include <windows.h>
7 #endif 7 #endif
8 8
9 #include "content/gpu/gpu_watchdog_thread.h" 9 #include "content/gpu/gpu_watchdog_thread.h"
10 10
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "build/build_config.h" 12 #include "build/build_config.h"
13 13
14 namespace { 14 namespace {
15 const int64 kCheckPeriod = 2000; 15 const int64 kCheckPeriod = 2000;
16 16
17 void DoNothing() { 17 void DoNothing() {
18 } 18 }
19 } 19 }
20 20
21 GpuWatchdogThread::GpuWatchdogThread(int timeout) 21 GpuWatchdogThread::GpuWatchdogThread(int timeout)
22 : base::Thread("Watchdog"), 22 : base::Thread("Watchdog"),
23 watched_message_loop_(MessageLoop::current()), 23 watched_message_loop_(MessageLoop::current()),
24 timeout_(timeout), 24 timeout_(timeout),
25 armed_(false), 25 armed_(false),
26 #if defined(OS_WIN) 26 #if defined(OS_WIN)
27 watched_thread_handle_(0), 27 watched_thread_handle_(0),
28 arm_cpu_time_(0), 28 arm_cpu_time_(0),
29 #endif 29 #endif
30 ALLOW_THIS_IN_INITIALIZER_LIST(task_observer_(this)) { 30 ALLOW_THIS_IN_INITIALIZER_LIST(closure_observer_(this)) {
31 DCHECK(timeout >= 0); 31 DCHECK(timeout >= 0);
32 32
33 #if defined(OS_WIN) 33 #if defined(OS_WIN)
34 // GetCurrentThread returns a pseudo-handle that cannot be used by one thread 34 // GetCurrentThread returns a pseudo-handle that cannot be used by one thread
35 // to identify another. DuplicateHandle creates a "real" handle that can be 35 // to identify another. DuplicateHandle creates a "real" handle that can be
36 // used for this purpose. 36 // used for this purpose.
37 BOOL result = DuplicateHandle(GetCurrentProcess(), 37 BOOL result = DuplicateHandle(GetCurrentProcess(),
38 GetCurrentThread(), 38 GetCurrentThread(),
39 GetCurrentProcess(), 39 GetCurrentProcess(),
40 &watched_thread_handle_, 40 &watched_thread_handle_,
41 THREAD_QUERY_INFORMATION, 41 THREAD_QUERY_INFORMATION,
42 FALSE, 42 FALSE,
43 0); 43 0);
44 DCHECK(result); 44 DCHECK(result);
45 #endif 45 #endif
46 46
47 watched_message_loop_->AddTaskObserver(&task_observer_); 47 watched_message_loop_->AddClosureObserver(&closure_observer_);
48 } 48 }
49 49
50 GpuWatchdogThread::~GpuWatchdogThread() { 50 GpuWatchdogThread::~GpuWatchdogThread() {
51 // Verify that the thread was explicitly stopped. If the thread is stopped 51 // Verify that the thread was explicitly stopped. If the thread is stopped
52 // implicitly by the destructor, CleanUp() will not be called. 52 // implicitly by the destructor, CleanUp() will not be called.
53 DCHECK(!method_factory_.get()); 53 DCHECK(!method_factory_.get());
54 54
55 #if defined(OS_WIN) 55 #if defined(OS_WIN)
56 CloseHandle(watched_thread_handle_); 56 CloseHandle(watched_thread_handle_);
57 #endif 57 #endif
58 58
59 watched_message_loop_->RemoveTaskObserver(&task_observer_); 59 watched_message_loop_->RemoveClosureObserver(&closure_observer_);
60 } 60 }
61 61
62 void GpuWatchdogThread::PostAcknowledge() { 62 void GpuWatchdogThread::PostAcknowledge() {
63 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use 63 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use
64 // the method factory. Rely on reference counting instead. 64 // the method factory. Rely on reference counting instead.
65 message_loop()->PostTask( 65 message_loop()->PostTask(
66 FROM_HERE, 66 FROM_HERE,
67 NewRunnableMethod(this, &GpuWatchdogThread::OnAcknowledge)); 67 NewRunnableMethod(this, &GpuWatchdogThread::OnAcknowledge));
68 } 68 }
69 69
70 void GpuWatchdogThread::Init() { 70 void GpuWatchdogThread::Init() {
71 // The method factory must be created on the watchdog thread. 71 // The method factory must be created on the watchdog thread.
72 method_factory_.reset(new MethodFactory(this)); 72 method_factory_.reset(new MethodFactory(this));
73 73
74 // Schedule the first check. 74 // Schedule the first check.
75 OnCheck(); 75 OnCheck();
76 } 76 }
77 77
78 void GpuWatchdogThread::CleanUp() { 78 void GpuWatchdogThread::CleanUp() {
79 // The method factory must be destroyed on the watchdog thread. 79 // The method factory must be destroyed on the watchdog thread.
80 method_factory_->RevokeAll(); 80 method_factory_->RevokeAll();
81 method_factory_.reset(); 81 method_factory_.reset();
82 } 82 }
83 83
84 GpuWatchdogThread::GpuWatchdogTaskObserver::GpuWatchdogTaskObserver( 84 GpuWatchdogThread::GpuWatchdogClosureObserver::GpuWatchdogClosureObserver(
85 GpuWatchdogThread* watchdog) 85 GpuWatchdogThread* watchdog)
86 : watchdog_(watchdog) { 86 : watchdog_(watchdog) {
87 } 87 }
88 88
89 GpuWatchdogThread::GpuWatchdogTaskObserver::~GpuWatchdogTaskObserver() { 89 GpuWatchdogThread::GpuWatchdogClosureObserver::~GpuWatchdogClosureObserver() {
90 } 90 }
91 91
92 void GpuWatchdogThread::GpuWatchdogTaskObserver::WillProcessTask( 92 void GpuWatchdogThread::GpuWatchdogClosureObserver::WillProcessClosure(
93 const Task* task) 93 base::TimeTicks time_posted) {
94 {
95 CheckArmed(); 94 CheckArmed();
96 } 95 }
97 96
98 void GpuWatchdogThread::GpuWatchdogTaskObserver::DidProcessTask( 97 void GpuWatchdogThread::GpuWatchdogClosureObserver::DidProcessClosure(
99 const Task* task) 98 base::TimeTicks time_posted) {
100 {
101 CheckArmed(); 99 CheckArmed();
102 } 100 }
103 101
104 void GpuWatchdogThread::GpuWatchdogTaskObserver::CheckArmed() 102 void GpuWatchdogThread::GpuWatchdogClosureObserver::CheckArmed() {
105 {
106 // Acknowledge the watchdog if it has armed itself. The watchdog will not 103 // Acknowledge the watchdog if it has armed itself. The watchdog will not
107 // change its armed state until it is acknowledged. 104 // change its armed state until it is acknowledged.
108 if (watchdog_->armed()) { 105 if (watchdog_->armed()) {
109 watchdog_->PostAcknowledge(); 106 watchdog_->PostAcknowledge();
110 } 107 }
111 } 108 }
112 109
113 void GpuWatchdogThread::OnAcknowledge() { 110 void GpuWatchdogThread::OnAcknowledge() {
114 // The check has already been acknowledged and another has already been 111 // The check has already been acknowledged and another has already been
115 // scheduled by a previous call to OnAcknowledge. It is normal for a 112 // scheduled by a previous call to OnAcknowledge. It is normal for a
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 return static_cast<int64>( 157 return static_cast<int64>(
161 (user_time64.QuadPart + kernel_time64.QuadPart) / 10000); 158 (user_time64.QuadPart + kernel_time64.QuadPart) / 10000);
162 } 159 }
163 #endif 160 #endif
164 161
165 void GpuWatchdogThread::OnCheck() { 162 void GpuWatchdogThread::OnCheck() {
166 if (armed_) 163 if (armed_)
167 return; 164 return;
168 165
169 // Must set armed before posting the task. This task might be the only task 166 // Must set armed before posting the task. This task might be the only task
170 // that will activate the TaskObserver on the watched thread and it must not 167 // that will activate the ClosureObserver on the watched thread and it must
171 // miss the false -> true transition. 168 // not miss the false -> true transition.
172 armed_ = true; 169 armed_ = true;
173 170
174 #if defined(OS_WIN) 171 #if defined(OS_WIN)
175 arm_cpu_time_ = GetWatchedThreadTime(); 172 arm_cpu_time_ = GetWatchedThreadTime();
176 #endif 173 #endif
177 174
178 arm_absolute_time_ = base::Time::Now(); 175 arm_absolute_time_ = base::Time::Now();
179 176
180 // Post a task to the monitored thread that does nothing but wake up the 177 // Post a task to the monitored thread that does nothing but wake up the
181 // TaskObserver. Any other tasks that are pending on the watched thread will 178 // ClosureObserver. Any other tasks that are pending on the watched thread
182 // also wake up the observer. This simply ensures there is at least one. 179 // will also wake up the observer. This simply ensures there is at least one.
183 watched_message_loop_->PostTask( 180 watched_message_loop_->PostTask(
184 FROM_HERE, 181 FROM_HERE,
185 NewRunnableFunction(DoNothing)); 182 NewRunnableFunction(DoNothing));
186 183
187 // Post a task to the watchdog thread to exit if the monitored thread does 184 // Post a task to the watchdog thread to exit if the monitored thread does
188 // not respond in time. 185 // not respond in time.
189 message_loop()->PostDelayedTask( 186 message_loop()->PostDelayedTask(
190 FROM_HERE, 187 FROM_HERE,
191 method_factory_->NewRunnableMethod( 188 method_factory_->NewRunnableMethod(
192 &GpuWatchdogThread::DeliberatelyCrashingToRecoverFromHang), 189 &GpuWatchdogThread::DeliberatelyCrashingToRecoverFromHang),
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 #endif 231 #endif
235 232
236 LOG(ERROR) << "The GPU process hung. Terminating after " 233 LOG(ERROR) << "The GPU process hung. Terminating after "
237 << timeout_ << " ms."; 234 << timeout_ << " ms.";
238 235
239 volatile int* null_pointer = NULL; 236 volatile int* null_pointer = NULL;
240 *null_pointer = timeout; 237 *null_pointer = timeout;
241 238
242 crashed = true; 239 crashed = true;
243 } 240 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698