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

Side by Side Diff: chrome/browser/metrics/thread_watcher.h

Issue 7134007: Added command line switches "crash-on-hang-threads" and "crash-on-hang-seconds" (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 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 | « chrome/browser/browser_main.cc ('k') | chrome/browser/metrics/thread_watcher.cc » ('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) 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 //
11 // ThreadWatcher class sends ping message to the watched thread and the watched 11 // ThreadWatcher class sends ping message to the watched thread and the watched
12 // thread responds back with a pong message. It uploads response time 12 // thread responds back with a pong message. It uploads response time
13 // (difference between ping and pong times) as a histogram. 13 // (difference between ping and pong times) as a histogram.
14 // 14 //
15 // TODO(raman): ThreadWatcher can detect hung threads. If a hung thread is 15 // TODO(raman): ThreadWatcher can detect hung threads. If a hung thread is
16 // detected, we should probably just crash, and allow the crash system to gather 16 // detected, we should probably just crash, and allow the crash system to gather
17 // then stack trace. 17 // then stack trace.
18 // 18 //
19 // Example Usage: 19 // Example Usage:
20 // 20 //
21 // The following is an example for watching responsiveness of IO thread. 21 // The following is an example for watching responsiveness of watched (IO)
22 // sleep_time specifies how often ping messages have to be sent to IO thread. 22 // thread. |sleep_time| specifies how often ping messages have to be sent to
23 // unresponsive_time is the wait time after ping message is sent, to check if 23 // watched (IO) thread. |unresponsive_time| is the wait time after ping
24 // we have received pong message or not. 24 // message is sent, to check if we have received pong message or not.
25 // |unresponsive_threshold| specifies the number of unanswered ping messages
26 // after which watched (IO) thread is considered as not responsive.
27 // |crash_on_hang| specifies if we want to crash the browser when the watched
28 // (IO) thread has become sufficiently unresponsive, while other threads are
29 // sufficiently responsive. |live_threads_threshold| specifies the number of
30 // browser threads that are to be responsive when we want to crash the browser
31 // because of hung watched (IO) thread.
25 // 32 //
26 // base::TimeDelta sleep_time = base::TimeDelta::FromSeconds(5); 33 // base::TimeDelta sleep_time = base::TimeDelta::FromSeconds(5);
27 // base::TimeDelta unresponsive_time = base::TimeDelta::FromSeconds(10); 34 // base::TimeDelta unresponsive_time = base::TimeDelta::FromSeconds(10);
28 // ThreadWatcher::StartWatching(BrowserThread::IO, "IO", sleep_time, 35 // uint32 unresponsive_threshold = ThreadWatcherList::kUnresponsiveCount;
29 // unresponsive_time); 36 // bool crash_on_hang = false;
37 // uint32 live_threads_threshold = ThreadWatcherList::kLiveThreadsThreshold;
38 // ThreadWatcher::StartWatching(
39 // BrowserThread::IO, "IO", sleep_time, unresponsive_time,
40 // unresponsive_threshold, crash_on_hang, live_threads_threshold);
30 41
31 #ifndef CHROME_BROWSER_METRICS_THREAD_WATCHER_H_ 42 #ifndef CHROME_BROWSER_METRICS_THREAD_WATCHER_H_
32 #define CHROME_BROWSER_METRICS_THREAD_WATCHER_H_ 43 #define CHROME_BROWSER_METRICS_THREAD_WATCHER_H_
33 44
34 #include <map> 45 #include <map>
46 #include <set>
35 #include <string> 47 #include <string>
36 #include <vector> 48 #include <vector>
37 49
38 #include "base/basictypes.h" 50 #include "base/basictypes.h"
51 #include "base/command_line.h"
39 #include "base/gtest_prod_util.h" 52 #include "base/gtest_prod_util.h"
40 #include "base/memory/ref_counted.h" 53 #include "base/memory/ref_counted.h"
41 #include "base/memory/scoped_ptr.h" 54 #include "base/memory/scoped_ptr.h"
42 #include "base/message_loop.h" 55 #include "base/message_loop.h"
43 #include "base/metrics/histogram.h" 56 #include "base/metrics/histogram.h"
44 #include "base/synchronization/lock.h" 57 #include "base/synchronization/lock.h"
45 #include "base/task.h" 58 #include "base/task.h"
46 #include "base/threading/thread.h" 59 #include "base/threading/thread.h"
47 #include "base/time.h" 60 #include "base/time.h"
48 #include "content/browser/browser_thread.h" 61 #include "content/browser/browser_thread.h"
49 #include "content/common/notification_observer.h" 62 #include "content/common/notification_observer.h"
50 #include "content/common/notification_registrar.h" 63 #include "content/common/notification_registrar.h"
51 64
52 class CustomThreadWatcher; 65 class CustomThreadWatcher;
53 class ThreadWatcherList; 66 class ThreadWatcherList;
67 class ThreadWatcherObserver;
54 68
55 // This class performs health check on threads that would like to be watched. 69 // This class performs health check on threads that would like to be watched.
56 class ThreadWatcher { 70 class ThreadWatcher {
57 public: 71 public:
58 // This method starts performing health check on the given thread_id. It will 72 // This method starts performing health check on the given |thread_id|. It
59 // create ThreadWatcher object for the given thread_id, thread_name, 73 // will create ThreadWatcher object for the given |thread_id|, |thread_name|.
60 // sleep_time and unresponsive_time. sleep_time_ is the wait time between ping 74 // |sleep_time| is the wait time between ping messages. |unresponsive_time| is
61 // messages. unresponsive_time_ is the wait time after ping message is sent, 75 // the wait time after ping message is sent, to check if we have received pong
62 // to check if we have received pong message or not. It will register that 76 // message or not. |unresponsive_threshold| is used to determine if the thread
63 // ThreadWatcher object and activate the thread watching of the given 77 // is responsive or not. The watched thread is considered unresponsive if it
64 // thread_id. 78 // hasn't responded with a pong message for |unresponsive_threshold| number of
79 // ping messages. |crash_on_hang| specifies if browser should be crashed when
80 // the watched thread is unresponsive. |live_threads_threshold| specifies the
81 // number of browser threads that are to be responsive when we want to crash
82 // the browser and watched thread has become sufficiently unresponsive. It
83 // will register that ThreadWatcher object and activate the thread watching of
84 // the given thread_id.
65 static void StartWatching(const BrowserThread::ID& thread_id, 85 static void StartWatching(const BrowserThread::ID& thread_id,
66 const std::string& thread_name, 86 const std::string& thread_name,
67 const base::TimeDelta& sleep_time, 87 const base::TimeDelta& sleep_time,
68 const base::TimeDelta& unresponsive_time); 88 const base::TimeDelta& unresponsive_time,
89 uint32 unresponsive_threshold,
90 bool crash_on_hang,
91 uint32 live_threads_threshold);
69 92
70 // Return the thread_id of the thread being watched. 93 // Return the |thread_id_| of the thread being watched.
71 BrowserThread::ID thread_id() const { return thread_id_; } 94 BrowserThread::ID thread_id() const { return thread_id_; }
72 95
73 // Return the name of the thread being watched. 96 // Return the name of the thread being watched.
74 std::string thread_name() const { return thread_name_; } 97 std::string thread_name() const { return thread_name_; }
75 98
76 // Return the sleep time between ping messages to be sent to the thread. 99 // Return the sleep time between ping messages to be sent to the thread.
77 base::TimeDelta sleep_time() const { return sleep_time_; } 100 base::TimeDelta sleep_time() const { return sleep_time_; }
78 101
79 // Return the the wait time to check the responsiveness of the thread. 102 // Return the the wait time to check the responsiveness of the thread.
80 base::TimeDelta unresponsive_time() const { return unresponsive_time_; } 103 base::TimeDelta unresponsive_time() const { return unresponsive_time_; }
81 104
82 // Returns true if we are montioring the thread. 105 // Returns true if we are montioring the thread.
83 bool active() const { return active_; } 106 bool active() const { return active_; }
84 107
85 // Returns ping_time_ (used by unit tests). 108 // Returns |ping_time_| (used by unit tests).
86 base::TimeTicks ping_time() const { return ping_time_; } 109 base::TimeTicks ping_time() const { return ping_time_; }
87 110
88 // Returns ping_sequence_number_ (used by unit tests). 111 // Returns |ping_sequence_number_| (used by unit tests).
89 uint64 ping_sequence_number() const { return ping_sequence_number_; } 112 uint64 ping_sequence_number() const { return ping_sequence_number_; }
90 113
91 protected: 114 protected:
92 // Construct a ThreadWatcher for the given thread_id. sleep_time_ is the 115 // Construct a ThreadWatcher for the given |thread_id|. |sleep_time| is the
93 // wait time between ping messages. unresponsive_time_ is the wait time after 116 // wait time between ping messages. |unresponsive_time| is the wait time after
94 // ping message is sent, to check if we have received pong message or not. 117 // ping message is sent, to check if we have received pong message or not.
95 ThreadWatcher(const BrowserThread::ID& thread_id, 118 ThreadWatcher(const BrowserThread::ID& thread_id,
96 const std::string& thread_name, 119 const std::string& thread_name,
97 const base::TimeDelta& sleep_time, 120 const base::TimeDelta& sleep_time,
98 const base::TimeDelta& unresponsive_time); 121 const base::TimeDelta& unresponsive_time,
122 uint32 unresponsive_threshold,
123 bool crash_on_hang,
124 uint32 live_threads_threshold);
99 virtual ~ThreadWatcher(); 125 virtual ~ThreadWatcher();
100 126
101 // This method activates the thread watching which starts ping/pong messaging. 127 // This method activates the thread watching which starts ping/pong messaging.
102 virtual void ActivateThreadWatching(); 128 virtual void ActivateThreadWatching();
103 129
104 // This method de-activates the thread watching and revokes all tasks. 130 // This method de-activates the thread watching and revokes all tasks.
105 virtual void DeActivateThreadWatching(); 131 virtual void DeActivateThreadWatching();
106 132
107 // This will ensure that the watching is actively taking place, and awaken 133 // This will ensure that the watching is actively taking place, and awaken
108 // (i.e., post a PostPingMessage) if the watcher has stopped pinging due to 134 // (i.e., post a PostPingMessage()) if the watcher has stopped pinging due to
109 // lack of user activity. It will also reset ping_count_ to kPingCount. 135 // lack of user activity. It will also reset |ping_count_| to |kPingCount|.
110 virtual void WakeUp(); 136 virtual void WakeUp();
111 137
112 // This method records when ping message was sent and it will Post a task 138 // This method records when ping message was sent and it will Post a task
113 // (OnPingMessage) to the watched thread that does nothing but respond with 139 // (OnPingMessage()) to the watched thread that does nothing but respond with
114 // OnPongMessage. It also posts a task (OnCheckResponsiveness) to check 140 // OnPongMessage(). It also posts a task (OnCheckResponsiveness()) to check
115 // responsiveness of monitored thread that would be called after waiting 141 // responsiveness of monitored thread that would be called after waiting
116 // unresponsive_time_. 142 // |unresponsive_time_|.
117 // This method is accessible on WatchDogThread. 143 // This method is accessible on WatchDogThread.
118 virtual void PostPingMessage(); 144 virtual void PostPingMessage();
119 145
120 // This method handles a Pong Message from watched thread. It will track the 146 // This method handles a Pong Message from watched thread. It will track the
121 // response time (pong time minus ping time) via histograms. It posts a 147 // response time (pong time minus ping time) via histograms. It posts a
122 // PostPingMessage task that would be called after waiting sleep_time_. It 148 // PostPingMessage() task that would be called after waiting |sleep_time_|. It
123 // increments ping_sequence_number_ by 1. 149 // increments |ping_sequence_number_| by 1.
124 // This method is accessible on WatchDogThread. 150 // This method is accessible on WatchDogThread.
125 virtual void OnPongMessage(uint64 ping_sequence_number); 151 virtual void OnPongMessage(uint64 ping_sequence_number);
126 152
127 // This method will determine if the watched thread is responsive or not. If 153 // This method will determine if the watched thread is responsive or not. If
128 // the latest ping_sequence_number_ is not same as the ping_sequence_number 154 // the latest |ping_sequence_number_| is not same as the
129 // that is passed in, then we can assume that watched thread has responded 155 // |ping_sequence_number| that is passed in, then we can assume that watched
130 // with a pong message. 156 // thread has responded with a pong message.
131 // This method is accessible on WatchDogThread. 157 // This method is accessible on WatchDogThread.
132 virtual bool OnCheckResponsiveness(uint64 ping_sequence_number); 158 virtual bool OnCheckResponsiveness(uint64 ping_sequence_number);
133 159
134 private: 160 private:
135 friend class ThreadWatcherList; 161 friend class ThreadWatcherList;
136 friend class CustomThreadWatcher; 162 friend class CustomThreadWatcher;
137 163
138 // Allow tests to access our innards for testing purposes. 164 // Allow tests to access our innards for testing purposes.
139 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, Registration); 165 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, Registration);
140 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadResponding); 166 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadResponding);
141 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadNotResponding); 167 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadNotResponding);
142 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsResponding); 168 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsResponding);
143 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsNotResponding); 169 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsNotResponding);
144 170
145 // Post constructor initialization. 171 // Post constructor initialization.
146 void Initialize(); 172 void Initialize();
147 173
148 // Watched thread does nothing except post callback_task to the WATCHDOG 174 // Watched thread does nothing except post callback_task to the WATCHDOG
149 // Thread. This method is called on watched thread. 175 // Thread. This method is called on watched thread.
150 static void OnPingMessage(const BrowserThread::ID& thread_id, 176 static void OnPingMessage(const BrowserThread::ID& thread_id,
151 Task* callback_task); 177 Task* callback_task);
152 178
153 // This method resets unresponsive_count_ to zero because watched thread is 179 // This method resets |unresponsive_count_| to zero because watched thread is
154 // responding to the ping message with a pong message. 180 // responding to the ping message with a pong message.
155 void ResetHangCounters(); 181 void ResetHangCounters();
156 182
157 // This method records watched thread is not responding to the ping message. 183 // This method records watched thread is not responding to the ping message.
158 // It increments unresponsive_count_ by 1. 184 // It increments |unresponsive_count_| by 1.
159 void GotNoResponse(); 185 void GotNoResponse();
160 186
187 // This method returns true if the watched thread has not responded with a
188 // pong message for |unresponsive_threshold_| number of ping messages.
189 bool IsVeryUnresponsive();
190
161 // This is the number of ping messages to be sent when the user is idle. 191 // This is the number of ping messages to be sent when the user is idle.
162 // ping_count_ will be initialized to kPingCount whenever user becomes active. 192 // ping_count_ will be initialized to kPingCount whenever user becomes active.
163 static const int kPingCount; 193 static const int kPingCount;
164 194
165 // This value is used to determine if the watched thread is responsive or not. 195 // The |thread_id_| of the thread being watched. Only one instance can exist
166 // If unresponsive_count_ is less than kUnresponsiveCount then watched thread 196 // for the given |thread_id_| of the thread being watched.
167 // is considered as responsive (in responsive_count_histogram_) otherwise it
168 // is considered as unresponsive (in unresponsive_count_histogram_).
169 static const int kUnresponsiveCount;
170
171 // The thread_id of the thread being watched. Only one instance can exist for
172 // the given thread_id of the thread being watched.
173 const BrowserThread::ID thread_id_; 197 const BrowserThread::ID thread_id_;
174 198
175 // The name of the thread being watched. 199 // The name of the thread being watched.
176 const std::string thread_name_; 200 const std::string thread_name_;
177 201
178 // It is the sleep time between between the receipt of a pong message back, 202 // It is the sleep time between the receipt of a pong message back, and the
179 // and the sending of another ping message. 203 // sending of another ping message.
180 const base::TimeDelta sleep_time_; 204 const base::TimeDelta sleep_time_;
181 205
182 // It is the duration from sending a ping message, until we check status to be 206 // It is the duration from sending a ping message, until we check status to be
183 // sure a pong message has been returned. 207 // sure a pong message has been returned.
184 const base::TimeDelta unresponsive_time_; 208 const base::TimeDelta unresponsive_time_;
185 209
186 // This is the last time when ping message was sent. 210 // This is the last time when ping message was sent.
187 base::TimeTicks ping_time_; 211 base::TimeTicks ping_time_;
188 212
189 // This is the last time when we got pong message. 213 // This is the last time when we got pong message.
(...skipping 10 matching lines...) Expand all
200 // The counter tracks least number of ping messages that will be sent to 224 // The counter tracks least number of ping messages that will be sent to
201 // watched thread before the ping-pong mechanism will go into an extended 225 // watched thread before the ping-pong mechanism will go into an extended
202 // sleep. If this value is zero, then the mechanism is in an extended sleep, 226 // sleep. If this value is zero, then the mechanism is in an extended sleep,
203 // and awaiting some observed user action before continuing. 227 // and awaiting some observed user action before continuing.
204 int ping_count_; 228 int ping_count_;
205 229
206 // Histogram that keeps track of response times for the watched thread. 230 // Histogram that keeps track of response times for the watched thread.
207 base::Histogram* response_time_histogram_; 231 base::Histogram* response_time_histogram_;
208 232
209 // Histogram that keeps track of unresponsive time since the last pong message 233 // Histogram that keeps track of unresponsive time since the last pong message
210 // when we got no response (GotNoResponse) from the watched thread. 234 // when we got no response (GotNoResponse()) from the watched thread.
211 base::Histogram* unresponsive_time_histogram_; 235 base::Histogram* unresponsive_time_histogram_;
212 236
213 // Histogram that keeps track of how many threads are responding when we got 237 // Histogram that keeps track of how many threads are responding when we got
214 // no response (GotNoResponse) from the watched thread. 238 // no response (GotNoResponse()) from the watched thread.
215 base::Histogram* responsive_count_histogram_; 239 base::Histogram* responsive_count_histogram_;
216 240
217 // Histogram that keeps track of how many threads are not responding when we 241 // Histogram that keeps track of how many threads are not responding when we
218 // got no response (GotNoResponse) from the watched thread. Count includes the 242 // got no response (GotNoResponse()) from the watched thread. Count includes
219 // thread that got no response. 243 // the thread that got no response.
220 base::Histogram* unresponsive_count_histogram_; 244 base::Histogram* unresponsive_count_histogram_;
221 245
222 // This counter tracks the unresponsiveness of watched thread. If this value 246 // This counter tracks the unresponsiveness of watched thread. If this value
223 // is zero then watched thread has responded with a pong message. This is 247 // is zero then watched thread has responded with a pong message. This is
224 // incremented by 1 when we got no response (GotNoResponse) from the watched 248 // incremented by 1 when we got no response (GotNoResponse()) from the watched
225 // thread. 249 // thread.
226 int unresponsive_count_; 250 uint32 unresponsive_count_;
227 251
228 // This is set to true when we would have crashed the browser because the 252 // This is set to true when we would have crashed the browser because the
229 // watched thread hasn't responded atleast 6 times. It is reset to false when 253 // watched thread hasn't responded atleast 6 times. It is reset to false when
230 // watched thread responds with a pong message. 254 // watched thread responds with a pong message.
231 bool hung_processing_complete_; 255 bool hung_processing_complete_;
232 256
257 // This is used to determine if the watched thread is responsive or not. If
258 // watched thread's |unresponsive_count_| is greater than or equal to
259 // |unresponsive_threshold_| then we would consider it as unresponsive.
260 uint32 unresponsive_threshold_;
261
262 // This is set to true if we want to crash the browser when the watched thread
263 // has become sufficiently unresponsive, while other threads are sufficiently
264 // responsive.
265 bool crash_on_hang_;
266
267 // This specifies the number of browser threads that are to be responsive when
268 // we want to crash the browser because watched thread has become sufficiently
269 // unresponsive.
270 uint32 live_threads_threshold_;
271
233 // We use this factory to create callback tasks for ThreadWatcher object. We 272 // We use this factory to create callback tasks for ThreadWatcher object. We
234 // use this during ping-pong messaging between WatchDog thread and watched 273 // use this during ping-pong messaging between WatchDog thread and watched
235 // thread. 274 // thread.
236 ScopedRunnableMethodFactory<ThreadWatcher> method_factory_; 275 ScopedRunnableMethodFactory<ThreadWatcher> method_factory_;
237 276
238 DISALLOW_COPY_AND_ASSIGN(ThreadWatcher); 277 DISALLOW_COPY_AND_ASSIGN(ThreadWatcher);
239 }; 278 };
240 279
241 // Class with a list of all active thread watchers. A thread watcher is active 280 // Class with a list of all active thread watchers. A thread watcher is active
242 // if it has been registered, which includes determing the histogram name. This 281 // if it has been registered, which includes determing the histogram name. This
243 // class provides utility functions to start and stop watching all browser 282 // class provides utility functions to start and stop watching all browser
244 // threads. Only one instance of this class exists. 283 // threads. Only one instance of this class exists.
245 class ThreadWatcherList : public NotificationObserver { 284 class ThreadWatcherList {
246 public: 285 public:
247 // A map from BrowserThread to the actual instances. 286 // A map from BrowserThread to the actual instances.
248 typedef std::map<BrowserThread::ID, ThreadWatcher*> RegistrationList; 287 typedef std::map<BrowserThread::ID, ThreadWatcher*> RegistrationList;
249 288
250 // This singleton holds the global list of registered ThreadWatchers.
251 ThreadWatcherList();
252 // Destructor deletes all registered ThreadWatcher instances.
253 virtual ~ThreadWatcherList();
254
255 // Register() stores a pointer to the given ThreadWatcher in a global map.
256 static void Register(ThreadWatcher* watcher);
257
258 // This method returns true if the ThreadWatcher object is registerd.
259 static bool IsRegistered(const BrowserThread::ID thread_id);
260
261 // This method posts a task on WatchDogThread to start watching all browser 289 // This method posts a task on WatchDogThread to start watching all browser
262 // threads. 290 // threads.
263 // This method is accessible on UI thread. 291 // This method is accessible on UI thread.
264 static void StartWatchingAll(); 292 static void StartWatchingAll(const CommandLine& command_line);
265 293
266 // This method posts a task on WatchDogThread to RevokeAll tasks and to 294 // This method posts a task on WatchDogThread to RevokeAll tasks and to
267 // deactive thread watching of other threads and tell NotificationService to 295 // deactive thread watching of other threads and tell NotificationService to
268 // stop calling Observe. 296 // stop calling Observe.
269 // This method is accessible on UI thread. 297 // This method is accessible on UI thread.
270 static void StopWatchingAll(); 298 static void StopWatchingAll();
271 299
272 // RemoveAll NotificationTypes that are being observed. 300 // Register() stores a pointer to the given ThreadWatcher in a global map.
273 // This method is accessible on UI thread. 301 static void Register(ThreadWatcher* watcher);
274 static void RemoveNotifications();
275 302
276 // This method returns number of watched threads that have responded and 303 // This method returns true if the ThreadWatcher object is registerd.
277 // threads that have not responded with a pong message. 304 static bool IsRegistered(const BrowserThread::ID thread_id);
278 static void GetStatusOfThreads(int* no_of_responding_threads, 305
279 int* no_of_unresponding_threads); 306 // This method returns number of responsive and unresponsive watched threads.
307 static void GetStatusOfThreads(uint32* responding_thread_count,
308 uint32* unresponding_thread_count);
309
310 // This will ensure that the watching is actively taking place, and awaken
311 // all thread watchers that are registered.
312 static void WakeUpAll();
280 313
281 private: 314 private:
282 // Allow tests to access our innards for testing purposes. 315 // Allow tests to access our innards for testing purposes.
283 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, Registration); 316 friend class CustomThreadWatcher;
317 friend class ThreadWatcherTest;
318 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, CommandLineArgs);
284 319
285 // Delete all thread watcher objects and remove them from global map. 320 // This singleton holds the global list of registered ThreadWatchers.
286 // This method is accessible on WatchDogThread. 321 ThreadWatcherList();
287 void DeleteAll();
288 322
289 // This will ensure that the watching is actively taking place. It will wakeup 323 // Destructor deletes all registered ThreadWatcher instances.
290 // all thread watchers every 2 seconds. This is the implementation of 324 virtual ~ThreadWatcherList();
291 // NotificationObserver. When a matching notification is posted to the
292 // notification service, this method is called.
293 // This method is accessible on UI thread.
294 virtual void Observe(NotificationType type,
295 const NotificationSource& source,
296 const NotificationDetails& details);
297 325
298 // This will ensure that the watching is actively taking place, and awaken 326 // Parses the command line to get |unresponsive_threshold| from
299 // all thread watchers that are registered. 327 // switches::kCrashOnHangSeconds, |crash_on_hang_thread_names| from
300 // This method is accessible on WatchDogThread. 328 // switches::kCrashOnHangThreads and |live_threads_threshold| from
301 virtual void WakeUpAll(); 329 // switches::kCrashOnLive. |crash_on_hang_thread_names| is the set of watched
330 // thread's names that are to be crashed if they are not responding.
331 static void ParseCommandLine(
332 const CommandLine& command_line,
333 uint32* unresponsive_threshold,
334 std::set<std::string>* crash_on_hang_thread_names,
335 uint32* live_threads_threshold);
336
337 // This constructs the |ThreadWatcherList| singleton and starts watching
338 // browser threads by calling StartWatching() on each browser thread that is
339 // watched.
340 static void InitializeAndStartWatching(
341 uint32 unresponsive_threshold,
342 const std::set<std::string>& crash_on_hang_thread_names,
343 uint32 live_threads_threshold);
344
345 // This method calls ThreadWatcher::StartWatching() to perform health check on
346 // the given |thread_id|.
347 static void StartWatching(
348 const BrowserThread::ID& thread_id,
349 const std::string& thread_name,
350 const base::TimeDelta& sleep_time,
351 const base::TimeDelta& unresponsive_time,
352 uint32 unresponsive_threshold,
353 const std::set<std::string>& crash_on_hang_thread_names,
354 uint32 live_threads_threshold);
355
356 // Delete all thread watcher objects and remove them from global map. It also
357 // deletes |g_thread_watcher_list_|.
358 static void DeleteAll();
302 359
303 // The Find() method can be used to test to see if a given ThreadWatcher was 360 // The Find() method can be used to test to see if a given ThreadWatcher was
304 // already registered, or to retrieve a pointer to it from the global map. 361 // already registered, or to retrieve a pointer to it from the global map.
305 static ThreadWatcher* Find(const BrowserThread::ID& thread_id); 362 static ThreadWatcher* Find(const BrowserThread::ID& thread_id);
306 363
307 // Helper function should be called only while holding lock_. 364 // The singleton of this class and is used to keep track of information about
308 ThreadWatcher* PreLockedFind(const BrowserThread::ID& thread_id); 365 // threads that are being watched.
309 366 static ThreadWatcherList* g_thread_watcher_list_;
310 static ThreadWatcherList* global_; // The singleton of this class.
311 367
312 // This is the wait time between ping messages. 368 // This is the wait time between ping messages.
313 static const int kSleepSeconds; 369 static const int kSleepSeconds;
314 370
315 // This is the wait time after ping message is sent, to check if we have 371 // This is the wait time after ping message is sent, to check if we have
316 // received pong message or not. 372 // received pong message or not.
317 static const int kUnresponsiveSeconds; 373 static const int kUnresponsiveSeconds;
318 374
319 // Lock for access to registered_. 375 // Default values for |unresponsive_threshold|.
320 base::Lock lock_; 376 static const int kUnresponsiveCount;
377
378 // Default values for |live_threads_threshold|.
379 static const int kLiveThreadsThreshold;
321 380
322 // Map of all registered watched threads, from thread_id to ThreadWatcher. 381 // Map of all registered watched threads, from thread_id to ThreadWatcher.
323 RegistrationList registered_; 382 RegistrationList registered_;
324 383
384 DISALLOW_COPY_AND_ASSIGN(ThreadWatcherList);
385 };
386
387 // This class ensures that the thread watching is actively taking place. Only
388 // one instance of this class exists.
389 class ThreadWatcherObserver : public NotificationObserver {
390 public:
391 // Registers |g_thread_watcher_observer_| as the Notifications observer.
392 // |wakeup_interval| specifies how often to wake up thread watchers. This
393 // method is accessible on UI thread.
394 static void SetupNotifications(const base::TimeDelta& wakeup_interval);
395
396 // Removes all NotificationTypes from |registrar_| and deletes
397 // |g_thread_watcher_observer_|. This method is accessible on UI thread.
398 static void RemoveNotifications();
399
400 private:
401 // Constructor of |g_thread_watcher_observer_| singleton.
402 explicit ThreadWatcherObserver(const base::TimeDelta& wakeup_interval);
403
404 // Destructor of |g_thread_watcher_observer_| singleton.
405 virtual ~ThreadWatcherObserver();
406
407 // This ensures all thread watchers are active because there is some user
408 // activity. It will wake up all thread watchers every |wakeup_interval_|
409 // seconds. This is the implementation of NotificationObserver. When a
410 // matching notification is posted to the notification service, this method is
411 // called.
412 virtual void Observe(NotificationType type,
413 const NotificationSource& source,
414 const NotificationDetails& details);
415
416 // The singleton of this class.
417 static ThreadWatcherObserver* g_thread_watcher_observer_;
418
325 // The registrar that holds NotificationTypes to be observed. 419 // The registrar that holds NotificationTypes to be observed.
326 NotificationRegistrar registrar_; 420 NotificationRegistrar registrar_;
327 421
328 // This is the last time when woke all thread watchers up. 422 // This is the last time when woke all thread watchers up.
329 base::TimeTicks last_wakeup_time_; 423 base::TimeTicks last_wakeup_time_;
330 424
331 DISALLOW_COPY_AND_ASSIGN(ThreadWatcherList); 425 // It is the time interval between wake up calls to thread watchers.
426 const base::TimeDelta wakeup_interval_;
427
428 DISALLOW_COPY_AND_ASSIGN(ThreadWatcherObserver);
332 }; 429 };
333 430
334 // Class for WatchDogThread and in its Init method, we start watching UI, IO, 431 // Class for WatchDogThread and in its Init method, we start watching UI, IO,
335 // DB, FILE, CACHED threads. 432 // DB, FILE, CACHED threads.
336 class WatchDogThread : public base::Thread { 433 class WatchDogThread : public base::Thread {
337 public: 434 public:
338 // Constructor. 435 // Constructor.
339 WatchDogThread(); 436 WatchDogThread();
340 437
341 // Destroys the thread and stops the thread. 438 // Destroys the thread and stops the thread.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 470
374 DISALLOW_COPY_AND_ASSIGN(WatchDogThread); 471 DISALLOW_COPY_AND_ASSIGN(WatchDogThread);
375 }; 472 };
376 473
377 // DISABLE_RUNNABLE_METHOD_REFCOUNT is a convenience macro for disabling 474 // DISABLE_RUNNABLE_METHOD_REFCOUNT is a convenience macro for disabling
378 // refcounting of ThreadWatcher and ThreadWatcherList classes. 475 // refcounting of ThreadWatcher and ThreadWatcherList classes.
379 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcher); 476 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcher);
380 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcherList); 477 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcherList);
381 478
382 #endif // CHROME_BROWSER_METRICS_THREAD_WATCHER_H_ 479 #endif // CHROME_BROWSER_METRICS_THREAD_WATCHER_H_
OLDNEW
« no previous file with comments | « chrome/browser/browser_main.cc ('k') | chrome/browser/metrics/thread_watcher.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698