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

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
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 IO thread.
22 // sleep_time specifies how often ping messages have to be sent to IO thread. 22 // sleep_time specifies how often ping messages have to be sent to IO thread.
23 // unresponsive_time is the wait time after ping message is sent, to check if 23 // unresponsive_time is the wait time after ping message is sent, to check if
24 // we have received pong message or not. 24 // we have received pong message or not.
25 // 25 //
26 // base::TimeDelta sleep_time = base::TimeDelta::FromSeconds(5); 26 // base::TimeDelta sleep_time = base::TimeDelta::FromSeconds(5);
27 // base::TimeDelta unresponsive_time = base::TimeDelta::FromSeconds(10); 27 // base::TimeDelta unresponsive_time = base::TimeDelta::FromSeconds(10);
28 // uint32 crash_on_unresponsive_count = ThreadWatcherList::kUnresponsiveCount;
29 // bool crash_on_hang = false;
28 // ThreadWatcher::StartWatching(BrowserThread::IO, "IO", sleep_time, 30 // ThreadWatcher::StartWatching(BrowserThread::IO, "IO", sleep_time,
29 // unresponsive_time); 31 // unresponsive_time,
32 // crash_on_unresponsive_count, crash_on_hang);
30 33
31 #ifndef CHROME_BROWSER_METRICS_THREAD_WATCHER_H_ 34 #ifndef CHROME_BROWSER_METRICS_THREAD_WATCHER_H_
32 #define CHROME_BROWSER_METRICS_THREAD_WATCHER_H_ 35 #define CHROME_BROWSER_METRICS_THREAD_WATCHER_H_
33 36
34 #include <map> 37 #include <map>
38 #include <set>
35 #include <string> 39 #include <string>
36 #include <vector> 40 #include <vector>
37 41
38 #include "base/basictypes.h" 42 #include "base/basictypes.h"
43 #include "base/command_line.h"
39 #include "base/gtest_prod_util.h" 44 #include "base/gtest_prod_util.h"
40 #include "base/memory/ref_counted.h" 45 #include "base/memory/ref_counted.h"
41 #include "base/memory/scoped_ptr.h" 46 #include "base/memory/scoped_ptr.h"
42 #include "base/message_loop.h" 47 #include "base/message_loop.h"
43 #include "base/metrics/histogram.h" 48 #include "base/metrics/histogram.h"
44 #include "base/synchronization/lock.h" 49 #include "base/synchronization/lock.h"
45 #include "base/task.h" 50 #include "base/task.h"
46 #include "base/threading/thread.h" 51 #include "base/threading/thread.h"
47 #include "base/time.h" 52 #include "base/time.h"
48 #include "content/browser/browser_thread.h" 53 #include "content/browser/browser_thread.h"
49 #include "content/common/notification_observer.h" 54 #include "content/common/notification_observer.h"
50 #include "content/common/notification_registrar.h" 55 #include "content/common/notification_registrar.h"
51 56
52 class CustomThreadWatcher; 57 class CustomThreadWatcher;
53 class ThreadWatcherList; 58 class ThreadWatcherList;
54 59
55 // This class performs health check on threads that would like to be watched. 60 // This class performs health check on threads that would like to be watched.
56 class ThreadWatcher { 61 class ThreadWatcher {
57 public: 62 public:
58 // This method starts performing health check on the given thread_id. It will 63 // This method starts performing health check on the given |thread_id|. It
59 // create ThreadWatcher object for the given thread_id, thread_name, 64 // 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 65 // |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, 66 // 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 67 // message or not. |crash_on_unresponsive_count| is used to determine if the
63 // ThreadWatcher object and activate the thread watching of the given 68 // thread is responsive or not. The watched thread is considered unresponsive
64 // thread_id. 69 // if it hasn't responded with a pong message for
70 // |crash_on_unresponsive_count| number of ping messages. |crash_on_hang|
71 // specifies if browser should be crashed when the watched thread is
72 // unresponsive. It will register that ThreadWatcher object and activate the
73 // thread watching of the given thread_id.
65 static void StartWatching(const BrowserThread::ID& thread_id, 74 static void StartWatching(const BrowserThread::ID& thread_id,
66 const std::string& thread_name, 75 const std::string& thread_name,
67 const base::TimeDelta& sleep_time, 76 const base::TimeDelta& sleep_time,
68 const base::TimeDelta& unresponsive_time); 77 const base::TimeDelta& unresponsive_time,
78 uint32 crash_on_unresponsive_count,
79 bool crash_on_hang);
69 80
70 // Return the thread_id of the thread being watched. 81 // Return the |thread_id_| of the thread being watched.
71 BrowserThread::ID thread_id() const { return thread_id_; } 82 BrowserThread::ID thread_id() const { return thread_id_; }
72 83
73 // Return the name of the thread being watched. 84 // Return the name of the thread being watched.
74 std::string thread_name() const { return thread_name_; } 85 std::string thread_name() const { return thread_name_; }
75 86
76 // Return the sleep time between ping messages to be sent to the thread. 87 // Return the sleep time between ping messages to be sent to the thread.
77 base::TimeDelta sleep_time() const { return sleep_time_; } 88 base::TimeDelta sleep_time() const { return sleep_time_; }
78 89
79 // Return the the wait time to check the responsiveness of the thread. 90 // Return the the wait time to check the responsiveness of the thread.
80 base::TimeDelta unresponsive_time() const { return unresponsive_time_; } 91 base::TimeDelta unresponsive_time() const { return unresponsive_time_; }
81 92
82 // Returns true if we are montioring the thread. 93 // Returns true if we are montioring the thread.
83 bool active() const { return active_; } 94 bool active() const { return active_; }
84 95
85 // Returns ping_time_ (used by unit tests). 96 // Returns |ping_time_| (used by unit tests).
86 base::TimeTicks ping_time() const { return ping_time_; } 97 base::TimeTicks ping_time() const { return ping_time_; }
87 98
88 // Returns ping_sequence_number_ (used by unit tests). 99 // Returns |ping_sequence_number_| (used by unit tests).
89 uint64 ping_sequence_number() const { return ping_sequence_number_; } 100 uint64 ping_sequence_number() const { return ping_sequence_number_; }
90 101
91 protected: 102 protected:
92 // Construct a ThreadWatcher for the given thread_id. sleep_time_ is the 103 // 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 104 // 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. 105 // ping message is sent, to check if we have received pong message or not.
106 // |crash_on_unresponsive_count| is used to determine if the thread is
107 // responsive or not. The watched thread is considered unresponsive if it
108 // hasn't responded with a pong message for |crash_on_unresponsive_count|
109 // number of ping messages. |crash_on_hang| specifies if browser should be
110 // crashed when the watched thread is unresponsive.
95 ThreadWatcher(const BrowserThread::ID& thread_id, 111 ThreadWatcher(const BrowserThread::ID& thread_id,
96 const std::string& thread_name, 112 const std::string& thread_name,
97 const base::TimeDelta& sleep_time, 113 const base::TimeDelta& sleep_time,
98 const base::TimeDelta& unresponsive_time); 114 const base::TimeDelta& unresponsive_time,
115 uint32 crash_on_unresponsive_count,
116 bool crash_on_hang);
99 virtual ~ThreadWatcher(); 117 virtual ~ThreadWatcher();
100 118
101 // This method activates the thread watching which starts ping/pong messaging. 119 // This method activates the thread watching which starts ping/pong messaging.
102 virtual void ActivateThreadWatching(); 120 virtual void ActivateThreadWatching();
103 121
104 // This method de-activates the thread watching and revokes all tasks. 122 // This method de-activates the thread watching and revokes all tasks.
105 virtual void DeActivateThreadWatching(); 123 virtual void DeActivateThreadWatching();
106 124
107 // This will ensure that the watching is actively taking place, and awaken 125 // 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 126 // (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. 127 // lack of user activity. It will also reset |ping_count_| to |kPingCount|.
110 virtual void WakeUp(); 128 virtual void WakeUp();
111 129
112 // This method records when ping message was sent and it will Post a task 130 // 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 131 // (OnPingMessage()) to the watched thread that does nothing but respond with
114 // OnPongMessage. It also posts a task (OnCheckResponsiveness) to check 132 // OnPongMessage(). It also posts a task (OnCheckResponsiveness()) to check
115 // responsiveness of monitored thread that would be called after waiting 133 // responsiveness of monitored thread that would be called after waiting
116 // unresponsive_time_. 134 // |unresponsive_time_|.
117 // This method is accessible on WatchDogThread. 135 // This method is accessible on WatchDogThread.
118 virtual void PostPingMessage(); 136 virtual void PostPingMessage();
119 137
120 // This method handles a Pong Message from watched thread. It will track the 138 // 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 139 // response time (pong time minus ping time) via histograms. It posts a
122 // PostPingMessage task that would be called after waiting sleep_time_. It 140 // PostPingMessage() task that would be called after waiting |sleep_time_|. It
123 // increments ping_sequence_number_ by 1. 141 // increments |ping_sequence_number_| by 1.
124 // This method is accessible on WatchDogThread. 142 // This method is accessible on WatchDogThread.
125 virtual void OnPongMessage(uint64 ping_sequence_number); 143 virtual void OnPongMessage(uint64 ping_sequence_number);
126 144
127 // This method will determine if the watched thread is responsive or not. If 145 // 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 146 // the latest |ping_sequence_number_| is not same as the
129 // that is passed in, then we can assume that watched thread has responded 147 // |ping_sequence_number| that is passed in, then we can assume that watched
130 // with a pong message. 148 // thread has responded with a pong message.
131 // This method is accessible on WatchDogThread. 149 // This method is accessible on WatchDogThread.
132 virtual bool OnCheckResponsiveness(uint64 ping_sequence_number); 150 virtual bool OnCheckResponsiveness(uint64 ping_sequence_number);
133 151
134 private: 152 private:
135 friend class ThreadWatcherList; 153 friend class ThreadWatcherList;
136 friend class CustomThreadWatcher; 154 friend class CustomThreadWatcher;
137 155
138 // Allow tests to access our innards for testing purposes. 156 // Allow tests to access our innards for testing purposes.
139 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, Registration); 157 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, Registration);
140 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadResponding); 158 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadResponding);
141 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadNotResponding); 159 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, ThreadNotResponding);
142 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsResponding); 160 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsResponding);
143 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsNotResponding); 161 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, MultipleThreadsNotResponding);
144 162
145 // Post constructor initialization. 163 // Post constructor initialization.
146 void Initialize(); 164 void Initialize();
147 165
148 // Watched thread does nothing except post callback_task to the WATCHDOG 166 // Watched thread does nothing except post callback_task to the WATCHDOG
149 // Thread. This method is called on watched thread. 167 // Thread. This method is called on watched thread.
150 static void OnPingMessage(const BrowserThread::ID& thread_id, 168 static void OnPingMessage(const BrowserThread::ID& thread_id,
151 Task* callback_task); 169 Task* callback_task);
152 170
153 // This method resets unresponsive_count_ to zero because watched thread is 171 // This method resets |unresponsive_count_| to zero because watched thread is
154 // responding to the ping message with a pong message. 172 // responding to the ping message with a pong message.
155 void ResetHangCounters(); 173 void ResetHangCounters();
156 174
157 // This method records watched thread is not responding to the ping message. 175 // This method records watched thread is not responding to the ping message.
158 // It increments unresponsive_count_ by 1. 176 // It increments |unresponsive_count_| by 1.
159 void GotNoResponse(); 177 void GotNoResponse();
160 178
179 // This method returns true if the watched thread has not responded with a
180 // pong message for |crash_on_unresponsive_count_| number of ping messages.
181 bool CrashOnUnresponsiveness();
182
161 // This is the number of ping messages to be sent when the user is idle. 183 // 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. 184 // ping_count_ will be initialized to kPingCount whenever user becomes active.
163 static const int kPingCount; 185 static const int kPingCount;
164 186
165 // This value is used to determine if the watched thread is responsive or not. 187 // The |thread_id_| of the thread being watched. Only one instance can exist
166 // If unresponsive_count_ is less than kUnresponsiveCount then watched thread 188 // 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_; 189 const BrowserThread::ID thread_id_;
174 190
175 // The name of the thread being watched. 191 // The name of the thread being watched.
176 const std::string thread_name_; 192 const std::string thread_name_;
177 193
178 // It is the sleep time between between the receipt of a pong message back, 194 // It is the sleep time between between the receipt of a pong message back,
179 // and the sending of another ping message. 195 // and the sending of another ping message.
180 const base::TimeDelta sleep_time_; 196 const base::TimeDelta sleep_time_;
181 197
182 // It is the duration from sending a ping message, until we check status to be 198 // It is the duration from sending a ping message, until we check status to be
(...skipping 17 matching lines...) Expand all
200 // The counter tracks least number of ping messages that will be sent to 216 // 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 217 // 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, 218 // sleep. If this value is zero, then the mechanism is in an extended sleep,
203 // and awaiting some observed user action before continuing. 219 // and awaiting some observed user action before continuing.
204 int ping_count_; 220 int ping_count_;
205 221
206 // Histogram that keeps track of response times for the watched thread. 222 // Histogram that keeps track of response times for the watched thread.
207 base::Histogram* response_time_histogram_; 223 base::Histogram* response_time_histogram_;
208 224
209 // Histogram that keeps track of unresponsive time since the last pong message 225 // Histogram that keeps track of unresponsive time since the last pong message
210 // when we got no response (GotNoResponse) from the watched thread. 226 // when we got no response (GotNoResponse()) from the watched thread.
211 base::Histogram* unresponsive_time_histogram_; 227 base::Histogram* unresponsive_time_histogram_;
212 228
213 // Histogram that keeps track of how many threads are responding when we got 229 // Histogram that keeps track of how many threads are responding when we got
214 // no response (GotNoResponse) from the watched thread. 230 // no response (GotNoResponse()) from the watched thread.
215 base::Histogram* responsive_count_histogram_; 231 base::Histogram* responsive_count_histogram_;
216 232
217 // Histogram that keeps track of how many threads are not responding when we 233 // 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 234 // got no response (GotNoResponse()) from the watched thread. Count includes
219 // thread that got no response. 235 // the thread that got no response.
220 base::Histogram* unresponsive_count_histogram_; 236 base::Histogram* unresponsive_count_histogram_;
221 237
222 // This counter tracks the unresponsiveness of watched thread. If this value 238 // 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 239 // 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 240 // incremented by 1 when we got no response (GotNoResponse()) from the watched
225 // thread. 241 // thread.
226 int unresponsive_count_; 242 uint32 unresponsive_count_;
227 243
228 // This is set to true when we would have crashed the browser because the 244 // 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 245 // watched thread hasn't responded atleast 6 times. It is reset to false when
230 // watched thread responds with a pong message. 246 // watched thread responds with a pong message.
231 bool hung_processing_complete_; 247 bool hung_processing_complete_;
232 248
249 // This is used to determine if the watched thread is responsive or not. If
250 // watched thread's |unresponsive_count_| is greater than or equal to
251 // |crash_on_unresponsive_count_| then we would consider it as unresponsive.
252 uint32 crash_on_unresponsive_count_;
jar (doing other things) 2011/06/14 00:56:27 nit: Consider changing the name. The count is abo
ramant (doing other things) 2011/06/16 22:26:45 Done.
253
254 // This is set to true if we want to the crash the browser when watched
255 // thread has not responded with a pong message for
256 // |crash_on_unresponsive_count_| number of ping messages.
jar (doing other things) 2011/06/14 00:56:27 Some of the comment are repetetive. It is nicer w
ramant (doing other things) 2011/06/16 22:26:45 Done.
257 bool crash_on_hang_;
258
233 // We use this factory to create callback tasks for ThreadWatcher object. We 259 // We use this factory to create callback tasks for ThreadWatcher object. We
234 // use this during ping-pong messaging between WatchDog thread and watched 260 // use this during ping-pong messaging between WatchDog thread and watched
235 // thread. 261 // thread.
236 ScopedRunnableMethodFactory<ThreadWatcher> method_factory_; 262 ScopedRunnableMethodFactory<ThreadWatcher> method_factory_;
237 263
238 DISALLOW_COPY_AND_ASSIGN(ThreadWatcher); 264 DISALLOW_COPY_AND_ASSIGN(ThreadWatcher);
239 }; 265 };
240 266
241 // Class with a list of all active thread watchers. A thread watcher is active 267 // 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 268 // if it has been registered, which includes determing the histogram name. This
243 // class provides utility functions to start and stop watching all browser 269 // class provides utility functions to start and stop watching all browser
244 // threads. Only one instance of this class exists. 270 // threads. Only one instance of this class exists.
245 class ThreadWatcherList : public NotificationObserver { 271 class ThreadWatcherList : public NotificationObserver {
246 public: 272 public:
247 // A map from BrowserThread to the actual instances. 273 // A map from BrowserThread to the actual instances.
248 typedef std::map<BrowserThread::ID, ThreadWatcher*> RegistrationList; 274 typedef std::map<BrowserThread::ID, ThreadWatcher*> RegistrationList;
249 275
250 // This singleton holds the global list of registered ThreadWatchers. 276 // This singleton holds the global list of registered ThreadWatchers.
251 ThreadWatcherList(); 277 explicit ThreadWatcherList(const CommandLine& command_line);
252 // Destructor deletes all registered ThreadWatcher instances. 278 // Destructor deletes all registered ThreadWatcher instances.
253 virtual ~ThreadWatcherList(); 279 virtual ~ThreadWatcherList();
254 280
255 // Register() stores a pointer to the given ThreadWatcher in a global map. 281 // Register() stores a pointer to the given ThreadWatcher in a global map.
256 static void Register(ThreadWatcher* watcher); 282 static void Register(ThreadWatcher* watcher);
257 283
258 // This method returns true if the ThreadWatcher object is registerd. 284 // This method returns true if the ThreadWatcher object is registerd.
259 static bool IsRegistered(const BrowserThread::ID thread_id); 285 static bool IsRegistered(const BrowserThread::ID thread_id);
260 286
261 // This method posts a task on WatchDogThread to start watching all browser 287 // This method posts a task on WatchDogThread to start watching all browser
262 // threads. 288 // threads. It calls ThreadWatcherList::StartWatching() on each browser thread
289 // that is watched.
263 // This method is accessible on UI thread. 290 // This method is accessible on UI thread.
264 static void StartWatchingAll(); 291 static void StartWatchingAll();
265 292
266 // This method posts a task on WatchDogThread to RevokeAll tasks and to 293 // This method posts a task on WatchDogThread to RevokeAll tasks and to
267 // deactive thread watching of other threads and tell NotificationService to 294 // deactive thread watching of other threads and tell NotificationService to
268 // stop calling Observe. 295 // stop calling Observe.
269 // This method is accessible on UI thread. 296 // This method is accessible on UI thread.
270 static void StopWatchingAll(); 297 static void StopWatchingAll();
271 298
272 // RemoveAll NotificationTypes that are being observed. 299 // RemoveAll NotificationTypes that are being observed.
273 // This method is accessible on UI thread. 300 // This method is accessible on UI thread.
274 static void RemoveNotifications(); 301 static void RemoveNotifications();
275 302
276 // This method returns number of watched threads that have responded and 303 // This method returns number of responsive and unresponsive watched threads.
277 // threads that have not responded with a pong message.
278 static void GetStatusOfThreads(int* no_of_responding_threads, 304 static void GetStatusOfThreads(int* no_of_responding_threads,
jar (doing other things) 2011/06/14 00:56:27 nit: abreviations should not be used in names in t
ramant (doing other things) 2011/06/16 22:26:45 Done.
279 int* no_of_unresponding_threads); 305 int* no_of_unresponding_threads);
280 306
281 private: 307 private:
282 // Allow tests to access our innards for testing purposes. 308 // Allow tests to access our innards for testing purposes.
309 friend class CustomThreadWatcher;
310 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, CommandLineArgs);
283 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, Registration); 311 FRIEND_TEST_ALL_PREFIXES(ThreadWatcherTest, Registration);
284 312
313 // This method calls ThreadWatcher::StartWatching() to perform health check on
314 // the given |thread_id|, |thread_name|. |sleep_time| is the wait time between
315 // ping messages. |unresponsive_time| is the wait time after ping message is
316 // sent, to check if we have received pong message or not.
317 static void StartWatching(const BrowserThread::ID& thread_id,
318 const std::string& thread_name,
319 const base::TimeDelta& sleep_time,
320 const base::TimeDelta& unresponsive_time);
321
322 // Helper methods to access crash_on_unresponsive_count_ (for unit tests).
323 uint32 CrashOnUnresponsiveCount();
324 uint32 PreLockedCrashOnUnresponsiveCount() const {
325 return crash_on_unresponsive_count_;
326 }
327
328 // Returns true if the |thread_name| is in the |crash_on_hang_thread_names_|.
329 bool CrashOnHang(const std::string& thread_name);
330 bool PreLockedCrashOnHang(const std::string& thread_name) const;
331
285 // Delete all thread watcher objects and remove them from global map. 332 // Delete all thread watcher objects and remove them from global map.
286 // This method is accessible on WatchDogThread. 333 // This method is accessible on WatchDogThread.
287 void DeleteAll(); 334 void DeleteAll();
288 335
289 // This will ensure that the watching is actively taking place. It will wakeup 336 // This will ensure that the watching is actively taking place. It will wakeup
290 // all thread watchers every 2 seconds. This is the implementation of 337 // all thread watchers every 2 seconds. This is the implementation of
291 // NotificationObserver. When a matching notification is posted to the 338 // NotificationObserver. When a matching notification is posted to the
292 // notification service, this method is called. 339 // notification service, this method is called.
293 // This method is accessible on UI thread. 340 // This method is accessible on UI thread.
294 virtual void Observe(NotificationType type, 341 virtual void Observe(NotificationType type,
(...skipping 14 matching lines...) Expand all
309 356
310 static ThreadWatcherList* global_; // The singleton of this class. 357 static ThreadWatcherList* global_; // The singleton of this class.
311 358
312 // This is the wait time between ping messages. 359 // This is the wait time between ping messages.
313 static const int kSleepSeconds; 360 static const int kSleepSeconds;
314 361
315 // This is the wait time after ping message is sent, to check if we have 362 // This is the wait time after ping message is sent, to check if we have
316 // received pong message or not. 363 // received pong message or not.
317 static const int kUnresponsiveSeconds; 364 static const int kUnresponsiveSeconds;
318 365
366 // Default values for |crash_on_unresponsive_count_|.
367 static const int kUnresponsiveCount;
368
319 // Lock for access to registered_. 369 // Lock for access to registered_.
320 base::Lock lock_; 370 base::Lock lock_;
321 371
322 // Map of all registered watched threads, from thread_id to ThreadWatcher. 372 // Map of all registered watched threads, from thread_id to ThreadWatcher.
323 RegistrationList registered_; 373 RegistrationList registered_;
324 374
325 // The registrar that holds NotificationTypes to be observed. 375 // The registrar that holds NotificationTypes to be observed.
326 NotificationRegistrar registrar_; 376 NotificationRegistrar registrar_;
327 377
328 // This is the last time when woke all thread watchers up. 378 // This is the last time when woke all thread watchers up.
329 base::TimeTicks last_wakeup_time_; 379 base::TimeTicks last_wakeup_time_;
330 380
381 // This is used to determine if the watched thread is responsive or not. If
382 // watched thread's |unresponsive_count_| is greater than or equal to
383 // |crash_on_unresponsive_count_| then we could crash the browser if the
384 // watched thread is in |crash_on_hang_thread_names_|.
385 // |crash_on_unresponsive_count_| is initialized with |kUnresponsiveCount|,
386 // but can be overwritten by the command line switch
387 // "--crash-on-hang-seconds".
388 uint32 crash_on_unresponsive_count_;
389
390 // This is the set of watched thread's names that are to be crashed if they
391 // have not responded with a pong message for |crash_on_unresponsive_count_|
392 // number of ping messages.
393 std::set<std::string> crash_on_hang_thread_names_;
394
331 DISALLOW_COPY_AND_ASSIGN(ThreadWatcherList); 395 DISALLOW_COPY_AND_ASSIGN(ThreadWatcherList);
332 }; 396 };
333 397
334 // Class for WatchDogThread and in its Init method, we start watching UI, IO, 398 // Class for WatchDogThread and in its Init method, we start watching UI, IO,
335 // DB, FILE, CACHED threads. 399 // DB, FILE, CACHED threads.
336 class WatchDogThread : public base::Thread { 400 class WatchDogThread : public base::Thread {
337 public: 401 public:
338 // Constructor. 402 // Constructor.
339 WatchDogThread(); 403 WatchDogThread();
340 404
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 437
374 DISALLOW_COPY_AND_ASSIGN(WatchDogThread); 438 DISALLOW_COPY_AND_ASSIGN(WatchDogThread);
375 }; 439 };
376 440
377 // DISABLE_RUNNABLE_METHOD_REFCOUNT is a convenience macro for disabling 441 // DISABLE_RUNNABLE_METHOD_REFCOUNT is a convenience macro for disabling
378 // refcounting of ThreadWatcher and ThreadWatcherList classes. 442 // refcounting of ThreadWatcher and ThreadWatcherList classes.
379 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcher); 443 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcher);
380 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcherList); 444 DISABLE_RUNNABLE_METHOD_REFCOUNT(ThreadWatcherList);
381 445
382 #endif // CHROME_BROWSER_METRICS_THREAD_WATCHER_H_ 446 #endif // CHROME_BROWSER_METRICS_THREAD_WATCHER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698