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

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

Issue 8572047: base::Bind() conversion for content/common/gpu and content/gpu (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: scoped_ptr<base::WPF> -> base::WPF Created 9 years, 1 month 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
« no previous file with comments | « content/gpu/gpu_watchdog_thread.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/bind.h"
11 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
12 #include "base/process_util.h" 13 #include "base/process_util.h"
13 #include "base/process.h" 14 #include "base/process.h"
14 #include "build/build_config.h" 15 #include "build/build_config.h"
15 #include "content/public/common/result_codes.h" 16 #include "content/public/common/result_codes.h"
16 17
17 namespace { 18 namespace {
18 const int64 kCheckPeriod = 2000; 19 const int64 kCheckPeriod = 2000;
19 20
20 void DoNothing() { 21 void DoNothing() {
21 } 22 }
22 } 23 }
23 24
24 GpuWatchdogThread::GpuWatchdogThread(int timeout) 25 GpuWatchdogThread::GpuWatchdogThread(int timeout)
25 : base::Thread("Watchdog"), 26 : base::Thread("Watchdog"),
26 watched_message_loop_(MessageLoop::current()), 27 watched_message_loop_(MessageLoop::current()),
27 timeout_(timeout), 28 timeout_(timeout),
28 armed_(false), 29 armed_(false),
29 #if defined(OS_WIN) 30 #if defined(OS_WIN)
30 watched_thread_handle_(0), 31 watched_thread_handle_(0),
31 arm_cpu_time_(0), 32 arm_cpu_time_(0),
32 #endif 33 #endif
33 ALLOW_THIS_IN_INITIALIZER_LIST(task_observer_(this)) { 34 ALLOW_THIS_IN_INITIALIZER_LIST(task_observer_(this)),
35 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
34 DCHECK(timeout >= 0); 36 DCHECK(timeout >= 0);
35 37
36 #if defined(OS_WIN) 38 #if defined(OS_WIN)
37 // GetCurrentThread returns a pseudo-handle that cannot be used by one thread 39 // GetCurrentThread returns a pseudo-handle that cannot be used by one thread
38 // to identify another. DuplicateHandle creates a "real" handle that can be 40 // to identify another. DuplicateHandle creates a "real" handle that can be
39 // used for this purpose. 41 // used for this purpose.
40 BOOL result = DuplicateHandle(GetCurrentProcess(), 42 BOOL result = DuplicateHandle(GetCurrentProcess(),
41 GetCurrentThread(), 43 GetCurrentThread(),
42 GetCurrentProcess(), 44 GetCurrentProcess(),
43 &watched_thread_handle_, 45 &watched_thread_handle_,
44 THREAD_QUERY_INFORMATION, 46 THREAD_QUERY_INFORMATION,
45 FALSE, 47 FALSE,
46 0); 48 0);
47 DCHECK(result); 49 DCHECK(result);
48 #endif 50 #endif
49 51
50 watched_message_loop_->AddTaskObserver(&task_observer_); 52 watched_message_loop_->AddTaskObserver(&task_observer_);
51 } 53 }
52 54
53 GpuWatchdogThread::~GpuWatchdogThread() { 55 GpuWatchdogThread::~GpuWatchdogThread() {
54 // Verify that the thread was explicitly stopped. If the thread is stopped 56 // Verify that the thread was explicitly stopped. If the thread is stopped
55 // implicitly by the destructor, CleanUp() will not be called. 57 // implicitly by the destructor, CleanUp() will not be called.
56 DCHECK(!method_factory_.get()); 58 DCHECK(!weak_factory_.HasWeakPtrs());
57 59
58 #if defined(OS_WIN) 60 #if defined(OS_WIN)
59 CloseHandle(watched_thread_handle_); 61 CloseHandle(watched_thread_handle_);
60 #endif 62 #endif
61 63
62 watched_message_loop_->RemoveTaskObserver(&task_observer_); 64 watched_message_loop_->RemoveTaskObserver(&task_observer_);
63 } 65 }
64 66
65 void GpuWatchdogThread::PostAcknowledge() { 67 void GpuWatchdogThread::PostAcknowledge() {
66 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use 68 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use
67 // the method factory. Rely on reference counting instead. 69 // the method factory. Rely on reference counting instead.
68 message_loop()->PostTask( 70 message_loop()->PostTask(
69 FROM_HERE, 71 FROM_HERE,
70 NewRunnableMethod(this, &GpuWatchdogThread::OnAcknowledge)); 72 base::Bind(&GpuWatchdogThread::OnAcknowledge, this));
71 } 73 }
72 74
73 void GpuWatchdogThread::Init() { 75 void GpuWatchdogThread::Init() {
74 // The method factory must be created on the watchdog thread.
75 method_factory_.reset(new MethodFactory(this));
76
77 // Schedule the first check. 76 // Schedule the first check.
78 OnCheck(); 77 OnCheck();
79 } 78 }
80 79
81 void GpuWatchdogThread::CleanUp() { 80 void GpuWatchdogThread::CleanUp() {
82 // The method factory must be destroyed on the watchdog thread. 81 weak_factory_.InvalidateWeakPtrs();
83 method_factory_->RevokeAll();
84 method_factory_.reset();
85 } 82 }
86 83
87 GpuWatchdogThread::GpuWatchdogTaskObserver::GpuWatchdogTaskObserver( 84 GpuWatchdogThread::GpuWatchdogTaskObserver::GpuWatchdogTaskObserver(
88 GpuWatchdogThread* watchdog) 85 GpuWatchdogThread* watchdog)
89 : watchdog_(watchdog) { 86 : watchdog_(watchdog) {
90 } 87 }
91 88
92 GpuWatchdogThread::GpuWatchdogTaskObserver::~GpuWatchdogTaskObserver() { 89 GpuWatchdogThread::GpuWatchdogTaskObserver::~GpuWatchdogTaskObserver() {
93 } 90 }
94 91
(...skipping 17 matching lines...) Expand all
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
116 // watched thread to see armed_ being true multiple times before 113 // watched thread to see armed_ being true multiple times before
117 // the OnAcknowledge task is run on the watchdog thread. 114 // the OnAcknowledge task is run on the watchdog thread.
118 if (!armed_) 115 if (!armed_)
119 return; 116 return;
120 117
121 // Revoke any pending hang termination. 118 // Revoke any pending hang termination.
122 method_factory_->RevokeAll(); 119 weak_factory_.InvalidateWeakPtrs();
123 armed_ = false; 120 armed_ = false;
124 121
125 // The monitored thread has responded. Post a task to check it again. 122 // The monitored thread has responded. Post a task to check it again.
126 message_loop()->PostDelayedTask( 123 message_loop()->PostDelayedTask(
127 FROM_HERE, 124 FROM_HERE,
128 method_factory_->NewRunnableMethod(&GpuWatchdogThread::OnCheck), 125 base::Bind(&GpuWatchdogThread::OnCheck, weak_factory_.GetWeakPtr()),
129 kCheckPeriod); 126 kCheckPeriod);
130 } 127 }
131 128
132 #if defined(OS_WIN) 129 #if defined(OS_WIN)
133 int64 GpuWatchdogThread::GetWatchedThreadTime() { 130 int64 GpuWatchdogThread::GetWatchedThreadTime() {
134 FILETIME creation_time; 131 FILETIME creation_time;
135 FILETIME exit_time; 132 FILETIME exit_time;
136 FILETIME user_time; 133 FILETIME user_time;
137 FILETIME kernel_time; 134 FILETIME kernel_time;
138 BOOL result = GetThreadTimes(watched_thread_handle_, 135 BOOL result = GetThreadTimes(watched_thread_handle_,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 // TaskObserver. Any other tasks that are pending on the watched thread will
182 // also wake up the observer. This simply ensures there is at least one. 179 // 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 base::Bind(&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 base::Bind(
192 &GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang), 189 &GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang,
190 weak_factory_.GetWeakPtr()),
193 timeout_); 191 timeout_);
194 } 192 }
195 193
196 // Use the --disable-gpu-watchdog command line switch to disable this. 194 // Use the --disable-gpu-watchdog command line switch to disable this.
197 void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() { 195 void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() {
198 #if defined(OS_WIN) 196 #if defined(OS_WIN)
199 // Defer termination until a certain amount of CPU time has elapsed on the 197 // Defer termination until a certain amount of CPU time has elapsed on the
200 // watched thread. 198 // watched thread.
201 int64 time_since_arm = GetWatchedThreadTime() - arm_cpu_time_; 199 int64 time_since_arm = GetWatchedThreadTime() - arm_cpu_time_;
202 if (time_since_arm < timeout_) { 200 if (time_since_arm < timeout_) {
203 message_loop()->PostDelayedTask( 201 message_loop()->PostDelayedTask(
204 FROM_HERE, 202 FROM_HERE,
205 method_factory_->NewRunnableMethod( 203 base::Bind(
206 &GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang), 204 &GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang,
205 weak_factory_.GetWeakPtr()),
207 timeout_ - time_since_arm); 206 timeout_ - time_since_arm);
208 return; 207 return;
209 } 208 }
210 #endif 209 #endif
211 210
212 // If the watchdog woke up significantly behind schedule, disarm and reset 211 // If the watchdog woke up significantly behind schedule, disarm and reset
213 // the watchdog check. This is to prevent the watchdog thread from terminating 212 // the watchdog check. This is to prevent the watchdog thread from terminating
214 // when a machine wakes up from sleep or hibernation, which would otherwise 213 // when a machine wakes up from sleep or hibernation, which would otherwise
215 // appear to be a hang. 214 // appear to be a hang.
216 if ((base::Time::Now() - arm_absolute_time_).InMilliseconds() > 215 if ((base::Time::Now() - arm_absolute_time_).InMilliseconds() >
(...skipping 16 matching lines...) Expand all
233 #endif 232 #endif
234 233
235 LOG(ERROR) << "The GPU process hung. Terminating after " 234 LOG(ERROR) << "The GPU process hung. Terminating after "
236 << timeout_ << " ms."; 235 << timeout_ << " ms.";
237 236
238 base::Process current_process(base::GetCurrentProcessHandle()); 237 base::Process current_process(base::GetCurrentProcessHandle());
239 current_process.Terminate(content::RESULT_CODE_HUNG); 238 current_process.Terminate(content::RESULT_CODE_HUNG);
240 239
241 terminated = true; 240 terminated = true;
242 } 241 }
OLDNEW
« no previous file with comments | « content/gpu/gpu_watchdog_thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698