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

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

Issue 10071038: RefCounted types should not have public destructors, content/browser part 2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Copyright bump Created 8 years, 7 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
« no previous file with comments | « content/gpu/gpu_watchdog_thread.h ('k') | content/renderer/devtools_agent_filter.h » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 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 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
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 &watched_thread_handle_, 43 &watched_thread_handle_,
44 THREAD_QUERY_INFORMATION, 44 THREAD_QUERY_INFORMATION,
45 FALSE, 45 FALSE,
46 0); 46 0);
47 DCHECK(result); 47 DCHECK(result);
48 #endif 48 #endif
49 49
50 watched_message_loop_->AddTaskObserver(&task_observer_); 50 watched_message_loop_->AddTaskObserver(&task_observer_);
51 } 51 }
52 52
53 GpuWatchdogThread::~GpuWatchdogThread() {
54 // Verify that the thread was explicitly stopped. If the thread is stopped
55 // implicitly by the destructor, CleanUp() will not be called.
56 DCHECK(!weak_factory_.HasWeakPtrs());
57
58 #if defined(OS_WIN)
59 CloseHandle(watched_thread_handle_);
60 #endif
61
62 watched_message_loop_->RemoveTaskObserver(&task_observer_);
63 }
64
65 void GpuWatchdogThread::PostAcknowledge() { 53 void GpuWatchdogThread::PostAcknowledge() {
66 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use 54 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use
67 // the method factory. Rely on reference counting instead. 55 // the method factory. Rely on reference counting instead.
68 message_loop()->PostTask( 56 message_loop()->PostTask(
69 FROM_HERE, 57 FROM_HERE,
70 base::Bind(&GpuWatchdogThread::OnAcknowledge, this)); 58 base::Bind(&GpuWatchdogThread::OnAcknowledge, this));
71 } 59 }
72 60
61 void GpuWatchdogThread::CheckArmed() {
62 // Acknowledge the watchdog if it has armed itself. The watchdog will not
63 // change its armed state until it is acknowledged.
64 if (armed()) {
65 PostAcknowledge();
66 }
67 }
68
73 void GpuWatchdogThread::Init() { 69 void GpuWatchdogThread::Init() {
74 // Schedule the first check. 70 // Schedule the first check.
75 OnCheck(); 71 OnCheck();
76 } 72 }
77 73
78 void GpuWatchdogThread::CleanUp() { 74 void GpuWatchdogThread::CleanUp() {
79 weak_factory_.InvalidateWeakPtrs(); 75 weak_factory_.InvalidateWeakPtrs();
80 } 76 }
81 77
82 GpuWatchdogThread::GpuWatchdogTaskObserver::GpuWatchdogTaskObserver( 78 GpuWatchdogThread::GpuWatchdogTaskObserver::GpuWatchdogTaskObserver(
83 GpuWatchdogThread* watchdog) 79 GpuWatchdogThread* watchdog)
84 : watchdog_(watchdog) { 80 : watchdog_(watchdog) {
85 } 81 }
86 82
87 GpuWatchdogThread::GpuWatchdogTaskObserver::~GpuWatchdogTaskObserver() { 83 GpuWatchdogThread::GpuWatchdogTaskObserver::~GpuWatchdogTaskObserver() {
88 } 84 }
89 85
90 void GpuWatchdogThread::GpuWatchdogTaskObserver::WillProcessTask( 86 void GpuWatchdogThread::GpuWatchdogTaskObserver::WillProcessTask(
91 base::TimeTicks time_posted) { 87 base::TimeTicks time_posted) {
92 watchdog_->CheckArmed(); 88 watchdog_->CheckArmed();
93 } 89 }
94 90
95 void GpuWatchdogThread::GpuWatchdogTaskObserver::DidProcessTask( 91 void GpuWatchdogThread::GpuWatchdogTaskObserver::DidProcessTask(
96 base::TimeTicks time_posted) { 92 base::TimeTicks time_posted) {
97 watchdog_->CheckArmed(); 93 watchdog_->CheckArmed();
98 } 94 }
99 95
100 void GpuWatchdogThread::CheckArmed() { 96 GpuWatchdogThread::~GpuWatchdogThread() {
101 // Acknowledge the watchdog if it has armed itself. The watchdog will not 97 // Verify that the thread was explicitly stopped. If the thread is stopped
102 // change its armed state until it is acknowledged. 98 // implicitly by the destructor, CleanUp() will not be called.
103 if (armed()) { 99 DCHECK(!weak_factory_.HasWeakPtrs());
104 PostAcknowledge(); 100
105 } 101 #if defined(OS_WIN)
102 CloseHandle(watched_thread_handle_);
103 #endif
104
105 watched_message_loop_->RemoveTaskObserver(&task_observer_);
106 } 106 }
107 107
108 void GpuWatchdogThread::OnAcknowledge() { 108 void GpuWatchdogThread::OnAcknowledge() {
109 // The check has already been acknowledged and another has already been 109 // The check has already been acknowledged and another has already been
110 // scheduled by a previous call to OnAcknowledge. It is normal for a 110 // scheduled by a previous call to OnAcknowledge. It is normal for a
111 // watched thread to see armed_ being true multiple times before 111 // watched thread to see armed_ being true multiple times before
112 // the OnAcknowledge task is run on the watchdog thread. 112 // the OnAcknowledge task is run on the watchdog thread.
113 if (!armed_) 113 if (!armed_)
114 return; 114 return;
115 115
116 // Revoke any pending hang termination. 116 // Revoke any pending hang termination.
117 weak_factory_.InvalidateWeakPtrs(); 117 weak_factory_.InvalidateWeakPtrs();
118 armed_ = false; 118 armed_ = false;
119 119
120 // The monitored thread has responded. Post a task to check it again. 120 // The monitored thread has responded. Post a task to check it again.
121 message_loop()->PostDelayedTask( 121 message_loop()->PostDelayedTask(
122 FROM_HERE, 122 FROM_HERE,
123 base::Bind(&GpuWatchdogThread::OnCheck, weak_factory_.GetWeakPtr()), 123 base::Bind(&GpuWatchdogThread::OnCheck, weak_factory_.GetWeakPtr()),
124 base::TimeDelta::FromMilliseconds(kCheckPeriodMs)); 124 base::TimeDelta::FromMilliseconds(kCheckPeriodMs));
125 } 125 }
126 126
127 #if defined(OS_WIN)
128 base::TimeDelta GpuWatchdogThread::GetWatchedThreadTime() {
129 FILETIME creation_time;
130 FILETIME exit_time;
131 FILETIME user_time;
132 FILETIME kernel_time;
133 BOOL result = GetThreadTimes(watched_thread_handle_,
134 &creation_time,
135 &exit_time,
136 &kernel_time,
137 &user_time);
138 DCHECK(result);
139
140 ULARGE_INTEGER user_time64;
141 user_time64.HighPart = user_time.dwHighDateTime;
142 user_time64.LowPart = user_time.dwLowDateTime;
143
144 ULARGE_INTEGER kernel_time64;
145 kernel_time64.HighPart = kernel_time.dwHighDateTime;
146 kernel_time64.LowPart = kernel_time.dwLowDateTime;
147
148 // Time is reported in units of 100 nanoseconds. Kernel and user time are
149 // summed to deal with to kinds of hangs. One is where the GPU process is
150 // stuck in user level, never calling into the kernel and kernel time is
151 // not increasing. The other is where either the kernel hangs and never
152 // returns to user level or where user level code
153 // calls into kernel level repeatedly, giving up its quanta before it is
154 // tracked, for example a loop that repeatedly Sleeps.
155 return base::TimeDelta::FromMilliseconds(static_cast<int64>(
156 (user_time64.QuadPart + kernel_time64.QuadPart) / 10000));
157 }
158 #endif
159
160 void GpuWatchdogThread::OnCheck() { 127 void GpuWatchdogThread::OnCheck() {
161 if (armed_) 128 if (armed_)
162 return; 129 return;
163 130
164 // Must set armed before posting the task. This task might be the only task 131 // Must set armed before posting the task. This task might be the only task
165 // that will activate the TaskObserver on the watched thread and it must not 132 // that will activate the TaskObserver on the watched thread and it must not
166 // miss the false -> true transition. 133 // miss the false -> true transition.
167 armed_ = true; 134 armed_ = true;
168 135
169 #if defined(OS_WIN) 136 #if defined(OS_WIN)
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 #endif 196 #endif
230 197
231 LOG(ERROR) << "The GPU process hung. Terminating after " 198 LOG(ERROR) << "The GPU process hung. Terminating after "
232 << timeout_.InMilliseconds() << " ms."; 199 << timeout_.InMilliseconds() << " ms.";
233 200
234 base::Process current_process(base::GetCurrentProcessHandle()); 201 base::Process current_process(base::GetCurrentProcessHandle());
235 current_process.Terminate(content::RESULT_CODE_HUNG); 202 current_process.Terminate(content::RESULT_CODE_HUNG);
236 203
237 terminated = true; 204 terminated = true;
238 } 205 }
206
207 #if defined(OS_WIN)
208 base::TimeDelta GpuWatchdogThread::GetWatchedThreadTime() {
209 FILETIME creation_time;
210 FILETIME exit_time;
211 FILETIME user_time;
212 FILETIME kernel_time;
213 BOOL result = GetThreadTimes(watched_thread_handle_,
214 &creation_time,
215 &exit_time,
216 &kernel_time,
217 &user_time);
218 DCHECK(result);
219
220 ULARGE_INTEGER user_time64;
221 user_time64.HighPart = user_time.dwHighDateTime;
222 user_time64.LowPart = user_time.dwLowDateTime;
223
224 ULARGE_INTEGER kernel_time64;
225 kernel_time64.HighPart = kernel_time.dwHighDateTime;
226 kernel_time64.LowPart = kernel_time.dwLowDateTime;
227
228 // Time is reported in units of 100 nanoseconds. Kernel and user time are
229 // summed to deal with to kinds of hangs. One is where the GPU process is
230 // stuck in user level, never calling into the kernel and kernel time is
231 // not increasing. The other is where either the kernel hangs and never
232 // returns to user level or where user level code
233 // calls into kernel level repeatedly, giving up its quanta before it is
234 // tracked, for example a loop that repeatedly Sleeps.
235 return base::TimeDelta::FromMilliseconds(static_cast<int64>(
236 (user_time64.QuadPart + kernel_time64.QuadPart) / 10000));
237 }
238 #endif
OLDNEW
« no previous file with comments | « content/gpu/gpu_watchdog_thread.h ('k') | content/renderer/devtools_agent_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698