OLD | NEW |
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 0 | |
6 | |
7 #include "base/threading/thread_restrictions.h" | 5 #include "base/threading/thread_restrictions.h" |
8 #include "build/build_config.h" | 6 #include "build/build_config.h" |
9 #include "chrome/browser/metrics/metrics_service.h" | 7 #include "chrome/browser/metrics/metrics_service.h" |
10 #include "chrome/browser/metrics/thread_watcher.h" | 8 #include "chrome/browser/metrics/thread_watcher.h" |
11 #include "chrome/common/notification_service.h" | 9 #include "chrome/common/notification_service.h" |
12 | 10 |
| 11 #if defined(OS_WIN) |
| 12 #include <Objbase.h> |
| 13 #endif |
| 14 |
13 // static | 15 // static |
14 const int ThreadWatcher::kPingCount = 3; | 16 const int ThreadWatcher::kPingCount = 3; |
15 | 17 |
16 //------------------------------------------------------------------------------ | 18 //------------------------------------------------------------------------------ |
17 // ThreadWatcher methods and members. | 19 // ThreadWatcher methods and members. |
18 | 20 |
19 ThreadWatcher::ThreadWatcher(const BrowserThread::ID thread_id, | 21 ThreadWatcher::ThreadWatcher(const BrowserThread::ID thread_id, |
20 const std::string& thread_name, | 22 const std::string& thread_name, |
21 const base::TimeDelta& sleep_time, | 23 const base::TimeDelta& sleep_time, |
22 const base::TimeDelta& unresponsive_time) | 24 const base::TimeDelta& unresponsive_time) |
(...skipping 12 matching lines...) Expand all Loading... |
35 ThreadWatcher::~ThreadWatcher() {} | 37 ThreadWatcher::~ThreadWatcher() {} |
36 | 38 |
37 // static | 39 // static |
38 void ThreadWatcher::StartWatching(const BrowserThread::ID thread_id, | 40 void ThreadWatcher::StartWatching(const BrowserThread::ID thread_id, |
39 const std::string& thread_name, | 41 const std::string& thread_name, |
40 const base::TimeDelta& sleep_time, | 42 const base::TimeDelta& sleep_time, |
41 const base::TimeDelta& unresponsive_time) { | 43 const base::TimeDelta& unresponsive_time) { |
42 DCHECK_GE(sleep_time.InMilliseconds(), 0); | 44 DCHECK_GE(sleep_time.InMilliseconds(), 0); |
43 DCHECK_GE(unresponsive_time.InMilliseconds(), sleep_time.InMilliseconds()); | 45 DCHECK_GE(unresponsive_time.InMilliseconds(), sleep_time.InMilliseconds()); |
44 | 46 |
45 // If we are not on WATCHDOG thread, then post a task to call StartWatching on | 47 // If we are not on WatchDogThread, then post a task to call StartWatching on |
46 // WATCHDOG thread. | 48 // WatchDogThread. |
47 if (!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)) { | 49 if (!WatchDogThread::CurrentlyOnWatchDogThread()) { |
48 BrowserThread::PostTask( | 50 MessageLoop* message_loop = WatchDogThread::CurrentMessageLoop(); |
49 BrowserThread::WATCHDOG, | 51 if (message_loop) |
50 FROM_HERE, | 52 message_loop->PostTask( |
51 NewRunnableFunction( | 53 FROM_HERE, |
52 &ThreadWatcher::StartWatching, | 54 NewRunnableFunction( |
53 thread_id, thread_name, sleep_time, unresponsive_time)); | 55 &ThreadWatcher::StartWatching, |
| 56 thread_id, thread_name, sleep_time, unresponsive_time)); |
54 return; | 57 return; |
55 } | 58 } |
56 | 59 |
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); | 60 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
58 | 61 |
59 // Create a new thread watcher object for the given thread and activate it. | 62 // Create a new thread watcher object for the given thread and activate it. |
60 ThreadWatcher* watcher = | 63 ThreadWatcher* watcher = |
61 new ThreadWatcher(thread_id, thread_name, sleep_time, unresponsive_time); | 64 new ThreadWatcher(thread_id, thread_name, sleep_time, unresponsive_time); |
62 DCHECK(watcher); | 65 DCHECK(watcher); |
63 watcher->ActivateThreadWatching(); | 66 watcher->ActivateThreadWatching(); |
64 } | 67 } |
65 | 68 |
66 void ThreadWatcher::ActivateThreadWatching() { | 69 void ThreadWatcher::ActivateThreadWatching() { |
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); | 70 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
68 if (active_) return; | 71 if (active_) return; |
69 active_ = true; | 72 active_ = true; |
70 ping_count_ = kPingCount; | 73 ping_count_ = kPingCount; |
71 MessageLoop::current()->PostTask( | 74 MessageLoop::current()->PostTask( |
72 FROM_HERE, | 75 FROM_HERE, |
73 method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage)); | 76 method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage)); |
74 } | 77 } |
75 | 78 |
76 void ThreadWatcher::DeActivateThreadWatching() { | 79 void ThreadWatcher::DeActivateThreadWatching() { |
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); | 80 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
78 active_ = false; | 81 active_ = false; |
79 ping_count_ = 0; | 82 ping_count_ = 0; |
80 method_factory_.RevokeAll(); | 83 method_factory_.RevokeAll(); |
81 } | 84 } |
82 | 85 |
83 void ThreadWatcher::WakeUp() { | 86 void ThreadWatcher::WakeUp() { |
84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); | 87 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
85 // There is some user activity, PostPingMessage task of thread watcher if | 88 // There is some user activity, PostPingMessage task of thread watcher if |
86 // needed. | 89 // needed. |
87 if (!active_) return; | 90 if (!active_) return; |
88 | 91 |
89 if (ping_count_ <= 0) { | 92 if (ping_count_ <= 0) { |
90 ping_count_ = kPingCount; | 93 ping_count_ = kPingCount; |
91 PostPingMessage(); | 94 PostPingMessage(); |
92 } else { | 95 } else { |
93 ping_count_ = kPingCount; | 96 ping_count_ = kPingCount; |
94 } | 97 } |
95 } | 98 } |
96 | 99 |
97 void ThreadWatcher::PostPingMessage() { | 100 void ThreadWatcher::PostPingMessage() { |
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); | 101 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
99 // If we have stopped watching or if the user is idle, then stop sending | 102 // If we have stopped watching or if the user is idle, then stop sending |
100 // ping messages. | 103 // ping messages. |
101 if (!active_ || ping_count_ <= 0) | 104 if (!active_ || ping_count_ <= 0) |
102 return; | 105 return; |
103 | 106 |
104 // Save the current time when we have sent ping message. | 107 // Save the current time when we have sent ping message. |
105 ping_time_ = base::TimeTicks::Now(); | 108 ping_time_ = base::TimeTicks::Now(); |
106 | 109 |
107 // Send a ping message to the watched thread. | 110 // Send a ping message to the watched thread. |
108 Task* callback_task = method_factory_.NewRunnableMethod( | 111 Task* callback_task = method_factory_.NewRunnableMethod( |
(...skipping 10 matching lines...) Expand all Loading... |
119 &ThreadWatcher::OnCheckResponsiveness, ping_sequence_number_), | 122 &ThreadWatcher::OnCheckResponsiveness, ping_sequence_number_), |
120 unresponsive_time_.InMilliseconds()); | 123 unresponsive_time_.InMilliseconds()); |
121 } else { | 124 } else { |
122 // Watched thread might have gone away, stop watching it. | 125 // Watched thread might have gone away, stop watching it. |
123 delete callback_task; | 126 delete callback_task; |
124 DeActivateThreadWatching(); | 127 DeActivateThreadWatching(); |
125 } | 128 } |
126 } | 129 } |
127 | 130 |
128 void ThreadWatcher::OnPongMessage(uint64 ping_sequence_number) { | 131 void ThreadWatcher::OnPongMessage(uint64 ping_sequence_number) { |
129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); | 132 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
130 // Record watched thread's response time. | 133 // Record watched thread's response time. |
131 base::TimeDelta response_time = base::TimeTicks::Now() - ping_time_; | 134 base::TimeDelta response_time = base::TimeTicks::Now() - ping_time_; |
132 histogram_->AddTime(response_time); | 135 histogram_->AddTime(response_time); |
133 | 136 |
134 // Check if there are any extra pings in flight. | 137 // Check if there are any extra pings in flight. |
135 DCHECK_EQ(ping_sequence_number_, ping_sequence_number); | 138 DCHECK_EQ(ping_sequence_number_, ping_sequence_number); |
136 if (ping_sequence_number_ != ping_sequence_number) | 139 if (ping_sequence_number_ != ping_sequence_number) |
137 return; | 140 return; |
138 | 141 |
139 // Increment sequence number for the next ping message to indicate watched | 142 // Increment sequence number for the next ping message to indicate watched |
140 // thread is responsive. | 143 // thread is responsive. |
141 ++ping_sequence_number_; | 144 ++ping_sequence_number_; |
142 | 145 |
143 // If we have stopped watching or if the user is idle, then stop sending | 146 // If we have stopped watching or if the user is idle, then stop sending |
144 // ping messages. | 147 // ping messages. |
145 if (!active_ || --ping_count_ <= 0) | 148 if (!active_ || --ping_count_ <= 0) |
146 return; | 149 return; |
147 | 150 |
148 MessageLoop::current()->PostDelayedTask( | 151 MessageLoop::current()->PostDelayedTask( |
149 FROM_HERE, | 152 FROM_HERE, |
150 method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage), | 153 method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage), |
151 sleep_time_.InMilliseconds()); | 154 sleep_time_.InMilliseconds()); |
152 } | 155 } |
153 | 156 |
154 bool ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) { | 157 bool ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) { |
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); | 158 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
156 // If we have stopped watching then consider thread as responding. | 159 // If we have stopped watching then consider thread as responding. |
157 if (!active_) | 160 if (!active_) |
158 return true; | 161 return true; |
159 // If the latest ping_sequence_number_ is not same as the ping_sequence_number | 162 // If the latest ping_sequence_number_ is not same as the ping_sequence_number |
160 // that is passed in, then we can assume OnPongMessage was called. | 163 // that is passed in, then we can assume OnPongMessage was called. |
161 // OnPongMessage increments ping_sequence_number_. | 164 // OnPongMessage increments ping_sequence_number_. |
162 if (ping_sequence_number_ != ping_sequence_number) | 165 if (ping_sequence_number_ != ping_sequence_number) |
163 return true; | 166 return true; |
164 return false; | 167 return false; |
165 } | 168 } |
166 | 169 |
167 void ThreadWatcher::Initialize() { | 170 void ThreadWatcher::Initialize() { |
168 ThreadWatcherList::Register(this); | 171 ThreadWatcherList::Register(this); |
169 histogram_ = base::Histogram::FactoryTimeGet( | 172 histogram_ = base::Histogram::FactoryTimeGet( |
170 "ThreadWatcher.ResponseTime." + thread_name_, | 173 "ThreadWatcher.ResponseTime." + thread_name_, |
171 base::TimeDelta::FromMilliseconds(1), | 174 base::TimeDelta::FromMilliseconds(1), |
172 base::TimeDelta::FromSeconds(100), 50, | 175 base::TimeDelta::FromSeconds(100), 50, |
173 base::Histogram::kUmaTargetedHistogramFlag); | 176 base::Histogram::kUmaTargetedHistogramFlag); |
174 } | 177 } |
175 | 178 |
176 // static | 179 // static |
177 void ThreadWatcher::OnPingMessage(const BrowserThread::ID thread_id, | 180 void ThreadWatcher::OnPingMessage(const BrowserThread::ID thread_id, |
178 Task* callback_task) { | 181 Task* callback_task) { |
179 // This method is called on watched thread. | 182 // This method is called on watched thread. |
180 DCHECK(BrowserThread::CurrentlyOn(thread_id)); | 183 DCHECK(BrowserThread::CurrentlyOn(thread_id)); |
181 BrowserThread::PostTask(BrowserThread::WATCHDOG, FROM_HERE, callback_task); | 184 MessageLoop* message_loop = WatchDogThread::CurrentMessageLoop(); |
| 185 if (message_loop) |
| 186 message_loop->PostTask(FROM_HERE, callback_task); |
| 187 else |
| 188 delete callback_task; |
182 } | 189 } |
183 | 190 |
184 //------------------------------------------------------------------------------ | 191 //------------------------------------------------------------------------------ |
185 // ThreadWatcherList methods and members. | 192 // ThreadWatcherList methods and members. |
186 | 193 |
187 // static | 194 // static |
188 ThreadWatcherList* ThreadWatcherList::global_ = NULL; | 195 ThreadWatcherList* ThreadWatcherList::global_ = NULL; |
189 | 196 |
190 ThreadWatcherList::ThreadWatcherList() | 197 ThreadWatcherList::ThreadWatcherList() |
191 : last_wakeup_time_(base::TimeTicks::Now()) { | 198 : last_wakeup_time_(base::TimeTicks::Now()) { |
192 // Assert we are not running on WATCHDOG thread. Would be ideal to assert we | 199 // Assert we are not running on WATCHDOG thread. Would be ideal to assert we |
193 // are on UI thread, but Unit tests are not running on UI thread. | 200 // are on UI thread, but Unit tests are not running on UI thread. |
194 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); | 201 DCHECK(!WatchDogThread::CurrentlyOnWatchDogThread()); |
195 DCHECK(!global_); | 202 CHECK(!global_); |
196 global_ = this; | 203 global_ = this; |
197 // Register Notifications observer. | 204 // Register Notifications observer. |
198 #if defined(OS_WIN) | |
199 MetricsService::SetupNotifications(®istrar_, this); | 205 MetricsService::SetupNotifications(®istrar_, this); |
200 #endif | |
201 } | 206 } |
202 | 207 |
203 ThreadWatcherList::~ThreadWatcherList() { | 208 ThreadWatcherList::~ThreadWatcherList() { |
204 base::AutoLock auto_lock(lock_); | 209 base::AutoLock auto_lock(lock_); |
205 while (!registered_.empty()) { | |
206 RegistrationList::iterator it = registered_.begin(); | |
207 delete it->second; | |
208 registered_.erase(it->first); | |
209 } | |
210 DCHECK(this == global_); | 210 DCHECK(this == global_); |
211 global_ = NULL; | 211 global_ = NULL; |
212 } | 212 } |
213 | 213 |
214 // static | 214 // static |
215 void ThreadWatcherList::Register(ThreadWatcher* watcher) { | 215 void ThreadWatcherList::Register(ThreadWatcher* watcher) { |
216 DCHECK(global_); | 216 DCHECK(global_); |
217 base::AutoLock auto_lock(global_->lock_); | 217 base::AutoLock auto_lock(global_->lock_); |
218 DCHECK(!global_->PreLockedFind(watcher->thread_id())); | 218 DCHECK(!global_->PreLockedFind(watcher->thread_id())); |
219 global_->registered_[watcher->thread_id()] = watcher; | 219 global_->registered_[watcher->thread_id()] = watcher; |
220 } | 220 } |
221 | 221 |
222 // static | 222 // static |
223 void ThreadWatcherList::StopWatchingAll() { | 223 void ThreadWatcherList::StopWatchingAll() { |
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
225 if (!global_) | 225 if (!global_) |
226 return; | 226 return; |
227 base::AutoLock auto_lock(global_->lock_); | 227 |
228 for (RegistrationList::iterator it = global_->registered_.begin(); | 228 // Remove all notifications for all watched threads. |
229 global_->registered_.end() != it; | 229 RemoveNotifications(); |
230 ++it) | 230 |
231 BrowserThread::PostTask( | 231 // Delete all thread watcher objects on WatchDogThread. |
232 BrowserThread::WATCHDOG, | 232 MessageLoop* message_loop = WatchDogThread::CurrentMessageLoop(); |
| 233 if (message_loop) |
| 234 message_loop->PostTask( |
233 FROM_HERE, | 235 FROM_HERE, |
234 NewRunnableMethod( | 236 NewRunnableMethod(global_, &ThreadWatcherList::DeleteAll)); |
235 it->second, &ThreadWatcher::DeActivateThreadWatching)); | |
236 } | 237 } |
237 | 238 |
238 // static | 239 // static |
239 void ThreadWatcherList::RemoveNotifications() { | 240 void ThreadWatcherList::RemoveNotifications() { |
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
241 if (!global_) | 242 if (!global_) |
242 return; | 243 return; |
243 #if defined(OS_WIN) | |
244 base::AutoLock auto_lock(global_->lock_); | 244 base::AutoLock auto_lock(global_->lock_); |
245 global_->registrar_.RemoveAll(); | 245 global_->registrar_.RemoveAll(); |
246 #endif | 246 } |
| 247 |
| 248 void ThreadWatcherList::DeleteAll() { |
| 249 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 250 base::AutoLock auto_lock(lock_); |
| 251 while (!registered_.empty()) { |
| 252 RegistrationList::iterator it = registered_.begin(); |
| 253 delete it->second; |
| 254 registered_.erase(it->first); |
| 255 } |
247 } | 256 } |
248 | 257 |
249 void ThreadWatcherList::Observe(NotificationType type, | 258 void ThreadWatcherList::Observe(NotificationType type, |
250 const NotificationSource& source, | 259 const NotificationSource& source, |
251 const NotificationDetails& details) { | 260 const NotificationDetails& details) { |
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
253 // There is some user activity, see if thread watchers are to be awakened. | 262 // There is some user activity, see if thread watchers are to be awakened. |
254 bool need_to_awaken = false; | 263 bool need_to_awaken = false; |
255 base::TimeTicks now = base::TimeTicks::Now(); | 264 base::TimeTicks now = base::TimeTicks::Now(); |
256 { | 265 { |
257 base::AutoLock lock(lock_); | 266 base::AutoLock lock(lock_); |
258 if (now - last_wakeup_time_ > base::TimeDelta::FromSeconds(2)) { | 267 if (now - last_wakeup_time_ > base::TimeDelta::FromSeconds(2)) { |
259 need_to_awaken = true; | 268 need_to_awaken = true; |
260 last_wakeup_time_ = now; | 269 last_wakeup_time_ = now; |
261 } | 270 } |
262 } | 271 } |
263 if (need_to_awaken) | 272 if (need_to_awaken) { |
264 BrowserThread::PostTask( | 273 MessageLoop* message_loop = WatchDogThread::CurrentMessageLoop(); |
265 BrowserThread::WATCHDOG, | 274 if (message_loop) |
266 FROM_HERE, | 275 message_loop->PostTask( |
267 NewRunnableMethod(this, &ThreadWatcherList::WakeUpAll)); | 276 FROM_HERE, |
| 277 NewRunnableMethod(this, &ThreadWatcherList::WakeUpAll)); |
| 278 } |
268 } | 279 } |
269 | 280 |
270 void ThreadWatcherList::WakeUpAll() { | 281 void ThreadWatcherList::WakeUpAll() { |
271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); | 282 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
272 base::AutoLock auto_lock(lock_); | 283 base::AutoLock auto_lock(lock_); |
273 for (RegistrationList::iterator it = global_->registered_.begin(); | 284 for (RegistrationList::iterator it = global_->registered_.begin(); |
274 global_->registered_.end() != it; | 285 global_->registered_.end() != it; |
275 ++it) | 286 ++it) |
276 it->second->WakeUp(); | 287 it->second->WakeUp(); |
277 } | 288 } |
278 | 289 |
279 // static | 290 // static |
280 ThreadWatcher* ThreadWatcherList::Find(const BrowserThread::ID thread_id) { | 291 ThreadWatcher* ThreadWatcherList::Find(const BrowserThread::ID thread_id) { |
281 DCHECK(global_); | 292 DCHECK(global_); |
282 base::AutoLock auto_lock(global_->lock_); | 293 base::AutoLock auto_lock(global_->lock_); |
283 return global_->PreLockedFind(thread_id); | 294 return global_->PreLockedFind(thread_id); |
284 } | 295 } |
285 | 296 |
286 ThreadWatcher* ThreadWatcherList::PreLockedFind( | 297 ThreadWatcher* ThreadWatcherList::PreLockedFind( |
287 const BrowserThread::ID thread_id) { | 298 const BrowserThread::ID thread_id) { |
288 RegistrationList::iterator it = registered_.find(thread_id); | 299 RegistrationList::iterator it = registered_.find(thread_id); |
289 if (registered_.end() == it) | 300 if (registered_.end() == it) |
290 return NULL; | 301 return NULL; |
291 return it->second; | 302 return it->second; |
292 } | 303 } |
293 | 304 |
294 //------------------------------------------------------------------------------ | 305 //------------------------------------------------------------------------------ |
295 // WatchDogThread methods and members. | 306 // WatchDogThread methods and members. |
296 | 307 |
| 308 // static |
| 309 base::Lock WatchDogThread::lock_; |
| 310 // static |
| 311 WatchDogThread* WatchDogThread::watchdog_thread_ = NULL; |
| 312 |
297 // The WatchDogThread object must outlive any tasks posted to the IO thread | 313 // The WatchDogThread object must outlive any tasks posted to the IO thread |
298 // before the Quit task. | 314 // before the Quit task. |
299 DISABLE_RUNNABLE_METHOD_REFCOUNT(WatchDogThread); | 315 DISABLE_RUNNABLE_METHOD_REFCOUNT(WatchDogThread); |
300 | 316 |
301 WatchDogThread::WatchDogThread() | 317 WatchDogThread::WatchDogThread() : Thread("WATCHDOG") { |
302 : BrowserProcessSubThread(BrowserThread::WATCHDOG) { | |
303 } | 318 } |
304 | 319 |
305 WatchDogThread::~WatchDogThread() { | 320 WatchDogThread::~WatchDogThread() { |
306 // Remove all notifications for all watched threads. | |
307 ThreadWatcherList::RemoveNotifications(); | |
308 // We cannot rely on our base class to stop the thread since we want our | 321 // We cannot rely on our base class to stop the thread since we want our |
309 // CleanUp function to run. | 322 // CleanUp function to run. |
310 Stop(); | 323 Stop(); |
311 } | 324 } |
312 | 325 |
| 326 void WatchDogThread::StartWatchingAll() { |
| 327 const base::TimeDelta kSleepTime = base::TimeDelta::FromSeconds(5); |
| 328 const base::TimeDelta kUnresponsiveTime = base::TimeDelta::FromSeconds(10); |
| 329 if (BrowserThread::IsMessageLoopValid(BrowserThread::UI)) |
| 330 ThreadWatcher::StartWatching(BrowserThread::UI, "UI", kSleepTime, |
| 331 kUnresponsiveTime); |
| 332 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) |
| 333 ThreadWatcher::StartWatching(BrowserThread::IO, "IO", kSleepTime, |
| 334 kUnresponsiveTime); |
| 335 if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) |
| 336 ThreadWatcher::StartWatching(BrowserThread::DB, "DB", kSleepTime, |
| 337 kUnresponsiveTime); |
| 338 if (BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) |
| 339 ThreadWatcher::StartWatching(BrowserThread::FILE, "FILE", kSleepTime, |
| 340 kUnresponsiveTime); |
| 341 if (BrowserThread::IsMessageLoopValid(BrowserThread::CACHE)) |
| 342 ThreadWatcher::StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime, |
| 343 kUnresponsiveTime); |
| 344 } |
| 345 |
| 346 // static |
| 347 MessageLoop* WatchDogThread::CurrentMessageLoop() { |
| 348 base::AutoLock lock(lock_); |
| 349 MessageLoop* message_loop = watchdog_thread_ ? |
| 350 watchdog_thread_->message_loop() : NULL; |
| 351 return message_loop; |
| 352 } |
| 353 |
| 354 // static |
| 355 bool WatchDogThread::CurrentlyOnWatchDogThread() { |
| 356 base::AutoLock lock(lock_); |
| 357 return watchdog_thread_ && |
| 358 watchdog_thread_->message_loop() == MessageLoop::current(); |
| 359 } |
| 360 |
313 void WatchDogThread::Init() { | 361 void WatchDogThread::Init() { |
314 // This thread shouldn't be allowed to perform any blocking disk I/O. | 362 // This thread shouldn't be allowed to perform any blocking disk I/O. |
315 base::ThreadRestrictions::SetIOAllowed(false); | 363 base::ThreadRestrictions::SetIOAllowed(false); |
316 | 364 |
317 BrowserProcessSubThread::Init(); | 365 #if defined(OS_WIN) |
| 366 // Initializes the COM library on the current thread. |
| 367 CoInitialize(NULL); |
| 368 #endif |
318 | 369 |
| 370 base::AutoLock lock(lock_); |
| 371 watchdog_thread_ = this; |
| 372 } |
| 373 |
| 374 void WatchDogThread::CleanUp() { |
| 375 base::AutoLock lock(lock_); |
| 376 watchdog_thread_ = NULL; |
| 377 } |
| 378 |
| 379 void WatchDogThread::CleanUpAfterMessageLoopDestruction() { |
319 #if defined(OS_WIN) | 380 #if defined(OS_WIN) |
320 const base::TimeDelta kSleepTime = base::TimeDelta::FromSeconds(5); | 381 // Closes the COM library on the current thread. CoInitialize must |
321 const base::TimeDelta kUnresponsiveTime = base::TimeDelta::FromSeconds(10); | 382 // be balanced by a corresponding call to CoUninitialize. |
322 ThreadWatcher::StartWatching(BrowserThread::UI, "UI", kSleepTime, | 383 CoUninitialize(); |
323 kUnresponsiveTime); | |
324 ThreadWatcher::StartWatching(BrowserThread::IO, "IO", kSleepTime, | |
325 kUnresponsiveTime); | |
326 ThreadWatcher::StartWatching(BrowserThread::DB, "DB", kSleepTime, | |
327 kUnresponsiveTime); | |
328 ThreadWatcher::StartWatching(BrowserThread::FILE, "FILE", kSleepTime, | |
329 kUnresponsiveTime); | |
330 ThreadWatcher::StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime, | |
331 kUnresponsiveTime); | |
332 #endif | 384 #endif |
333 } | 385 } |
334 | |
335 #endif // 0 | |
OLD | NEW |