| 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 // This file defines a WatchDog thread that monitors the responsiveness of other | 5 // This file defines a WatchDog thread that monitors the responsiveness of other |
| 6 // browser threads like UI, IO, DB, FILE and CACHED threads. It also defines | 6 // browser threads like UI, IO, DB, FILE and CACHED threads. It also defines |
| 7 // ThreadWatcher class which performs health check on threads that would like to | 7 // ThreadWatcher class which performs health check on threads that would like to |
| 8 // be watched. This file also defines ThreadWatcherList class that has list of | 8 // be watched. This file also defines ThreadWatcherList class that has list of |
| 9 // all active ThreadWatcher objects. | 9 // all active ThreadWatcher objects. |
| 10 // | 10 // |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 class StartupTimeBomb; | 67 class StartupTimeBomb; |
| 68 class ThreadWatcherList; | 68 class ThreadWatcherList; |
| 69 class ThreadWatcherObserver; | 69 class ThreadWatcherObserver; |
| 70 | 70 |
| 71 // This class performs health check on threads that would like to be watched. | 71 // This class performs health check on threads that would like to be watched. |
| 72 class ThreadWatcher { | 72 class ThreadWatcher { |
| 73 public: | 73 public: |
| 74 // base::Bind supports methods with up to 6 parameters. WatchingParams is used | 74 // base::Bind supports methods with up to 6 parameters. WatchingParams is used |
| 75 // as a workaround that limitation for invoking ThreadWatcher::StartWatching. | 75 // as a workaround that limitation for invoking ThreadWatcher::StartWatching. |
| 76 struct WatchingParams { | 76 struct WatchingParams { |
| 77 const BrowserThread::ID& thread_id; | 77 const content::BrowserThread::ID& thread_id; |
| 78 const std::string& thread_name; | 78 const std::string& thread_name; |
| 79 const base::TimeDelta& sleep_time; | 79 const base::TimeDelta& sleep_time; |
| 80 const base::TimeDelta& unresponsive_time; | 80 const base::TimeDelta& unresponsive_time; |
| 81 uint32 unresponsive_threshold; | 81 uint32 unresponsive_threshold; |
| 82 bool crash_on_hang; | 82 bool crash_on_hang; |
| 83 uint32 live_threads_threshold; | 83 uint32 live_threads_threshold; |
| 84 | 84 |
| 85 WatchingParams(const BrowserThread::ID& thread_id_in, | 85 WatchingParams(const content::BrowserThread::ID& thread_id_in, |
| 86 const std::string& thread_name_in, | 86 const std::string& thread_name_in, |
| 87 const base::TimeDelta& sleep_time_in, | 87 const base::TimeDelta& sleep_time_in, |
| 88 const base::TimeDelta& unresponsive_time_in, | 88 const base::TimeDelta& unresponsive_time_in, |
| 89 uint32 unresponsive_threshold_in, | 89 uint32 unresponsive_threshold_in, |
| 90 bool crash_on_hang_in, | 90 bool crash_on_hang_in, |
| 91 uint32 live_threads_threshold_in) | 91 uint32 live_threads_threshold_in) |
| 92 : thread_id(thread_id_in), | 92 : thread_id(thread_id_in), |
| 93 thread_name(thread_name_in), | 93 thread_name(thread_name_in), |
| 94 sleep_time(sleep_time_in), | 94 sleep_time(sleep_time_in), |
| 95 unresponsive_time(unresponsive_time_in), | 95 unresponsive_time(unresponsive_time_in), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 108 // hasn't responded with a pong message for |unresponsive_threshold| number of | 108 // hasn't responded with a pong message for |unresponsive_threshold| number of |
| 109 // ping messages. |crash_on_hang| specifies if browser should be crashed when | 109 // ping messages. |crash_on_hang| specifies if browser should be crashed when |
| 110 // the watched thread is unresponsive. |live_threads_threshold| specifies the | 110 // the watched thread is unresponsive. |live_threads_threshold| specifies the |
| 111 // number of browser threads that are to be responsive when we want to crash | 111 // number of browser threads that are to be responsive when we want to crash |
| 112 // the browser and watched thread has become sufficiently unresponsive. It | 112 // the browser and watched thread has become sufficiently unresponsive. It |
| 113 // will register that ThreadWatcher object and activate the thread watching of | 113 // will register that ThreadWatcher object and activate the thread watching of |
| 114 // the given thread_id. | 114 // the given thread_id. |
| 115 static void StartWatching(const WatchingParams& params); | 115 static void StartWatching(const WatchingParams& params); |
| 116 | 116 |
| 117 // Return the |thread_id_| of the thread being watched. | 117 // Return the |thread_id_| of the thread being watched. |
| 118 BrowserThread::ID thread_id() const { return thread_id_; } | 118 content::BrowserThread::ID thread_id() const { return thread_id_; } |
| 119 | 119 |
| 120 // Return the name of the thread being watched. | 120 // Return the name of the thread being watched. |
| 121 std::string thread_name() const { return thread_name_; } | 121 std::string thread_name() const { return thread_name_; } |
| 122 | 122 |
| 123 // Return the sleep time between ping messages to be sent to the thread. | 123 // Return the sleep time between ping messages to be sent to the thread. |
| 124 base::TimeDelta sleep_time() const { return sleep_time_; } | 124 base::TimeDelta sleep_time() const { return sleep_time_; } |
| 125 | 125 |
| 126 // Return the the wait time to check the responsiveness of the thread. | 126 // Return the the wait time to check the responsiveness of the thread. |
| 127 base::TimeDelta unresponsive_time() const { return unresponsive_time_; } | 127 base::TimeDelta unresponsive_time() const { return unresponsive_time_; } |
| 128 | 128 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadResponding); | 190 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadResponding); |
| 191 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadNotResponding); | 191 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadNotResponding); |
| 192 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsResponding); | 192 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsResponding); |
| 193 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsNotResponding); | 193 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsNotResponding); |
| 194 | 194 |
| 195 // Post constructor initialization. | 195 // Post constructor initialization. |
| 196 void Initialize(); | 196 void Initialize(); |
| 197 | 197 |
| 198 // Watched thread does nothing except post callback_task to the WATCHDOG | 198 // Watched thread does nothing except post callback_task to the WATCHDOG |
| 199 // Thread. This method is called on watched thread. | 199 // Thread. This method is called on watched thread. |
| 200 static void OnPingMessage(const BrowserThread::ID& thread_id, | 200 static void OnPingMessage(const content::BrowserThread::ID& thread_id, |
| 201 const base::Closure& callback_task); | 201 const base::Closure& callback_task); |
| 202 | 202 |
| 203 // This method resets |unresponsive_count_| to zero because watched thread is | 203 // This method resets |unresponsive_count_| to zero because watched thread is |
| 204 // responding to the ping message with a pong message. | 204 // responding to the ping message with a pong message. |
| 205 void ResetHangCounters(); | 205 void ResetHangCounters(); |
| 206 | 206 |
| 207 // This method records watched thread is not responding to the ping message. | 207 // This method records watched thread is not responding to the ping message. |
| 208 // It increments |unresponsive_count_| by 1. | 208 // It increments |unresponsive_count_| by 1. |
| 209 void GotNoResponse(); | 209 void GotNoResponse(); |
| 210 | 210 |
| 211 // This method returns true if the watched thread has not responded with a | 211 // This method returns true if the watched thread has not responded with a |
| 212 // pong message for |unresponsive_threshold_| number of ping messages. | 212 // pong message for |unresponsive_threshold_| number of ping messages. |
| 213 bool IsVeryUnresponsive(); | 213 bool IsVeryUnresponsive(); |
| 214 | 214 |
| 215 // The |thread_id_| of the thread being watched. Only one instance can exist | 215 // The |thread_id_| of the thread being watched. Only one instance can exist |
| 216 // for the given |thread_id_| of the thread being watched. | 216 // for the given |thread_id_| of the thread being watched. |
| 217 const BrowserThread::ID thread_id_; | 217 const content::BrowserThread::ID thread_id_; |
| 218 | 218 |
| 219 // The name of the thread being watched. | 219 // The name of the thread being watched. |
| 220 const std::string thread_name_; | 220 const std::string thread_name_; |
| 221 | 221 |
| 222 // Used to post messages to watched thread. | 222 // Used to post messages to watched thread. |
| 223 scoped_refptr<base::MessageLoopProxy> watched_loop_; | 223 scoped_refptr<base::MessageLoopProxy> watched_loop_; |
| 224 | 224 |
| 225 // It is the sleep time between the receipt of a pong message back, and the | 225 // It is the sleep time between the receipt of a pong message back, and the |
| 226 // sending of another ping message. | 226 // sending of another ping message. |
| 227 const base::TimeDelta sleep_time_; | 227 const base::TimeDelta sleep_time_; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 DISALLOW_COPY_AND_ASSIGN(ThreadWatcher); | 300 DISALLOW_COPY_AND_ASSIGN(ThreadWatcher); |
| 301 }; | 301 }; |
| 302 | 302 |
| 303 // Class with a list of all active thread watchers. A thread watcher is active | 303 // Class with a list of all active thread watchers. A thread watcher is active |
| 304 // if it has been registered, which includes determing the histogram name. This | 304 // if it has been registered, which includes determing the histogram name. This |
| 305 // class provides utility functions to start and stop watching all browser | 305 // class provides utility functions to start and stop watching all browser |
| 306 // threads. Only one instance of this class exists. | 306 // threads. Only one instance of this class exists. |
| 307 class ThreadWatcherList { | 307 class ThreadWatcherList { |
| 308 public: | 308 public: |
| 309 // A map from BrowserThread to the actual instances. | 309 // A map from BrowserThread to the actual instances. |
| 310 typedef std::map<BrowserThread::ID, ThreadWatcher*> RegistrationList; | 310 typedef std::map<content::BrowserThread::ID, ThreadWatcher*> RegistrationList; |
| 311 | 311 |
| 312 // This method posts a task on WatchDogThread to start watching all browser | 312 // This method posts a task on WatchDogThread to start watching all browser |
| 313 // threads. | 313 // threads. |
| 314 // This method is accessible on UI thread. | 314 // This method is accessible on UI thread. |
| 315 static void StartWatchingAll(const CommandLine& command_line); | 315 static void StartWatchingAll(const CommandLine& command_line); |
| 316 | 316 |
| 317 // This method posts a task on WatchDogThread to RevokeAll tasks and to | 317 // This method posts a task on WatchDogThread to RevokeAll tasks and to |
| 318 // deactive thread watching of other threads and tell NotificationService to | 318 // deactive thread watching of other threads and tell NotificationService to |
| 319 // stop calling Observe. | 319 // stop calling Observe. |
| 320 // This method is accessible on UI thread. | 320 // This method is accessible on UI thread. |
| 321 static void StopWatchingAll(); | 321 static void StopWatchingAll(); |
| 322 | 322 |
| 323 // Register() stores a pointer to the given ThreadWatcher in a global map. | 323 // Register() stores a pointer to the given ThreadWatcher in a global map. |
| 324 static void Register(ThreadWatcher* watcher); | 324 static void Register(ThreadWatcher* watcher); |
| 325 | 325 |
| 326 // This method returns true if the ThreadWatcher object is registerd. | 326 // This method returns true if the ThreadWatcher object is registerd. |
| 327 static bool IsRegistered(const BrowserThread::ID thread_id); | 327 static bool IsRegistered(const content::BrowserThread::ID thread_id); |
| 328 | 328 |
| 329 // This method returns number of responsive and unresponsive watched threads. | 329 // This method returns number of responsive and unresponsive watched threads. |
| 330 static void GetStatusOfThreads(uint32* responding_thread_count, | 330 static void GetStatusOfThreads(uint32* responding_thread_count, |
| 331 uint32* unresponding_thread_count); | 331 uint32* unresponding_thread_count); |
| 332 | 332 |
| 333 // This will ensure that the watching is actively taking place, and awaken | 333 // This will ensure that the watching is actively taking place, and awaken |
| 334 // all thread watchers that are registered. | 334 // all thread watchers that are registered. |
| 335 static void WakeUpAll(); | 335 static void WakeUpAll(); |
| 336 | 336 |
| 337 private: | 337 private: |
| (...skipping 23 matching lines...) Expand all Loading... |
| 361 // browser threads by calling StartWatching() on each browser thread that is | 361 // browser threads by calling StartWatching() on each browser thread that is |
| 362 // watched. It disarms StartupTimeBomb. | 362 // watched. It disarms StartupTimeBomb. |
| 363 static void InitializeAndStartWatching( | 363 static void InitializeAndStartWatching( |
| 364 uint32 unresponsive_threshold, | 364 uint32 unresponsive_threshold, |
| 365 const std::set<std::string>& crash_on_hang_thread_names, | 365 const std::set<std::string>& crash_on_hang_thread_names, |
| 366 uint32 live_threads_threshold); | 366 uint32 live_threads_threshold); |
| 367 | 367 |
| 368 // This method calls ThreadWatcher::StartWatching() to perform health check on | 368 // This method calls ThreadWatcher::StartWatching() to perform health check on |
| 369 // the given |thread_id|. | 369 // the given |thread_id|. |
| 370 static void StartWatching( | 370 static void StartWatching( |
| 371 const BrowserThread::ID& thread_id, | 371 const content::BrowserThread::ID& thread_id, |
| 372 const std::string& thread_name, | 372 const std::string& thread_name, |
| 373 const base::TimeDelta& sleep_time, | 373 const base::TimeDelta& sleep_time, |
| 374 const base::TimeDelta& unresponsive_time, | 374 const base::TimeDelta& unresponsive_time, |
| 375 uint32 unresponsive_threshold, | 375 uint32 unresponsive_threshold, |
| 376 const std::set<std::string>& crash_on_hang_thread_names, | 376 const std::set<std::string>& crash_on_hang_thread_names, |
| 377 uint32 live_threads_threshold); | 377 uint32 live_threads_threshold); |
| 378 | 378 |
| 379 // Delete all thread watcher objects and remove them from global map. It also | 379 // Delete all thread watcher objects and remove them from global map. It also |
| 380 // deletes |g_thread_watcher_list_|. | 380 // deletes |g_thread_watcher_list_|. |
| 381 static void DeleteAll(); | 381 static void DeleteAll(); |
| 382 | 382 |
| 383 // The Find() method can be used to test to see if a given ThreadWatcher was | 383 // The Find() method can be used to test to see if a given ThreadWatcher was |
| 384 // already registered, or to retrieve a pointer to it from the global map. | 384 // already registered, or to retrieve a pointer to it from the global map. |
| 385 static ThreadWatcher* Find(const BrowserThread::ID& thread_id); | 385 static ThreadWatcher* Find(const content::BrowserThread::ID& thread_id); |
| 386 | 386 |
| 387 // The singleton of this class and is used to keep track of information about | 387 // The singleton of this class and is used to keep track of information about |
| 388 // threads that are being watched. | 388 // threads that are being watched. |
| 389 static ThreadWatcherList* g_thread_watcher_list_; | 389 static ThreadWatcherList* g_thread_watcher_list_; |
| 390 | 390 |
| 391 // This is the wait time between ping messages. | 391 // This is the wait time between ping messages. |
| 392 static const int kSleepSeconds; | 392 static const int kSleepSeconds; |
| 393 | 393 |
| 394 // This is the wait time after ping message is sent, to check if we have | 394 // This is the wait time after ping message is sent, to check if we have |
| 395 // received pong message or not. | 395 // received pong message or not. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 | 533 |
| 534 DISALLOW_COPY_AND_ASSIGN(ShutdownWatcherHelper); | 534 DISALLOW_COPY_AND_ASSIGN(ShutdownWatcherHelper); |
| 535 }; | 535 }; |
| 536 | 536 |
| 537 // DISABLE_RUNNABLE_METHOD_REFCOUNT is a convenience macro for disabling | 537 // DISABLE_RUNNABLE_METHOD_REFCOUNT is a convenience macro for disabling |
| 538 // refcounting of ThreadWatcher and ThreadWatcherList classes. | 538 // refcounting of ThreadWatcher and ThreadWatcherList classes. |
| 539 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcher); | 539 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcher); |
| 540 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcherList); | 540 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcherList); |
| 541 | 541 |
| 542 #endif // CHROME_BROWSER_METRICS_THREAD_WATCHER_H_ | 542 #endif // CHROME_BROWSER_METRICS_THREAD_WATCHER_H_ |
| OLD | NEW |