OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "base/tracked_objects.h" | 5 #include "base/tracked_objects.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 13 #include "base/thread_restrictions.h" |
13 | 14 |
14 using base::TimeDelta; | 15 using base::TimeDelta; |
15 | 16 |
16 namespace tracked_objects { | 17 namespace tracked_objects { |
17 | 18 |
18 // A TLS slot to the TrackRegistry for the current thread. | 19 // A TLS slot to the TrackRegistry for the current thread. |
19 // static | 20 // static |
20 TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED); | 21 TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED); |
21 | 22 |
22 // A global state variable to prevent repeated initialization during tests. | 23 // A global state variable to prevent repeated initialization during tests. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 // ThreadData maintains the central data for all births and death. | 83 // ThreadData maintains the central data for all births and death. |
83 | 84 |
84 // static | 85 // static |
85 ThreadData* ThreadData::first_ = NULL; | 86 ThreadData* ThreadData::first_ = NULL; |
86 // static | 87 // static |
87 Lock ThreadData::list_lock_; | 88 Lock ThreadData::list_lock_; |
88 | 89 |
89 // static | 90 // static |
90 ThreadData::Status ThreadData::status_ = ThreadData::UNINITIALIZED; | 91 ThreadData::Status ThreadData::status_ = ThreadData::UNINITIALIZED; |
91 | 92 |
92 ThreadData::ThreadData() : next_(NULL), message_loop_(MessageLoop::current()) {} | 93 ThreadData::ThreadData() : next_(NULL) { |
| 94 // This shouldn't use the MessageLoop::current() LazyInstance since this might |
| 95 // be used on a non-joinable thread. |
| 96 // http://crbug.com/62728 |
| 97 base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton; |
| 98 message_loop_ = MessageLoop::current(); |
| 99 } |
93 | 100 |
94 ThreadData::~ThreadData() {} | 101 ThreadData::~ThreadData() {} |
95 | 102 |
96 // static | 103 // static |
97 ThreadData* ThreadData::current() { | 104 ThreadData* ThreadData::current() { |
98 if (!tls_index_.initialized()) | 105 if (!tls_index_.initialized()) |
99 return NULL; | 106 return NULL; |
100 | 107 |
101 ThreadData* registry = static_cast<ThreadData*>(tls_index_.Get()); | 108 ThreadData* registry = static_cast<ThreadData*>(tls_index_.Get()); |
102 if (!registry) { | 109 if (!registry) { |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 output->append("<br>"); | 260 output->append("<br>"); |
254 subtotals.Write(output); | 261 subtotals.Write(output); |
255 output->append("<br><hr><br>"); | 262 output->append("<br><hr><br>"); |
256 subtotals.Clear(); | 263 subtotals.Clear(); |
257 } | 264 } |
258 } | 265 } |
259 } | 266 } |
260 } | 267 } |
261 | 268 |
262 Births* ThreadData::TallyABirth(const Location& location) { | 269 Births* ThreadData::TallyABirth(const Location& location) { |
263 if (!message_loop_) // In case message loop wasn't yet around... | 270 { |
264 message_loop_ = MessageLoop::current(); // Find it now. | 271 // This shouldn't use the MessageLoop::current() LazyInstance since this |
| 272 // might be used on a non-joinable thread. |
| 273 // http://crbug.com/62728 |
| 274 base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton; |
| 275 if (!message_loop_) // In case message loop wasn't yet around... |
| 276 message_loop_ = MessageLoop::current(); // Find it now. |
| 277 } |
265 | 278 |
266 BirthMap::iterator it = birth_map_.find(location); | 279 BirthMap::iterator it = birth_map_.find(location); |
267 if (it != birth_map_.end()) { | 280 if (it != birth_map_.end()) { |
268 it->second->RecordBirth(); | 281 it->second->RecordBirth(); |
269 return it->second; | 282 return it->second; |
270 } | 283 } |
271 | 284 |
272 Births* tracker = new Births(location); | 285 Births* tracker = new Births(location); |
273 // Lock since the map may get relocated now, and other threads sometimes | 286 // Lock since the map may get relocated now, and other threads sometimes |
274 // snapshot it (but they lock before copying it). | 287 // snapshot it (but they lock before copying it). |
275 AutoLock lock(lock_); | 288 AutoLock lock(lock_); |
276 birth_map_[location] = tracker; | 289 birth_map_[location] = tracker; |
277 return tracker; | 290 return tracker; |
278 } | 291 } |
279 | 292 |
280 void ThreadData::TallyADeath(const Births& lifetimes, | 293 void ThreadData::TallyADeath(const Births& lifetimes, |
281 const TimeDelta& duration) { | 294 const TimeDelta& duration) { |
282 if (!message_loop_) // In case message loop wasn't yet around... | 295 { |
283 message_loop_ = MessageLoop::current(); // Find it now. | 296 // http://crbug.com/62728 |
| 297 base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton; |
| 298 if (!message_loop_) // In case message loop wasn't yet around... |
| 299 message_loop_ = MessageLoop::current(); // Find it now. |
| 300 } |
284 | 301 |
285 DeathMap::iterator it = death_map_.find(&lifetimes); | 302 DeathMap::iterator it = death_map_.find(&lifetimes); |
286 if (it != death_map_.end()) { | 303 if (it != death_map_.end()) { |
287 it->second.RecordDeath(duration); | 304 it->second.RecordDeath(duration); |
288 return; | 305 return; |
289 } | 306 } |
290 | 307 |
291 AutoLock lock(lock_); // Lock since the map may get relocated now. | 308 AutoLock lock(lock_); // Lock since the map may get relocated now. |
292 death_map_[&lifetimes].RecordDeath(duration); | 309 death_map_[&lifetimes].RecordDeath(duration); |
293 } | 310 } |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 (combined_selectors_ & BIRTH_THREAD) ? "*" : | 1049 (combined_selectors_ & BIRTH_THREAD) ? "*" : |
1033 sample.birth().birth_thread()->ThreadName().c_str(), | 1050 sample.birth().birth_thread()->ThreadName().c_str(), |
1034 (combined_selectors_ & DEATH_THREAD) ? "*" : | 1051 (combined_selectors_ & DEATH_THREAD) ? "*" : |
1035 sample.DeathThreadName().c_str()); | 1052 sample.DeathThreadName().c_str()); |
1036 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE), | 1053 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE), |
1037 !(combined_selectors_ & BIRTH_FUNCTION), | 1054 !(combined_selectors_ & BIRTH_FUNCTION), |
1038 output); | 1055 output); |
1039 } | 1056 } |
1040 | 1057 |
1041 } // namespace tracked_objects | 1058 } // namespace tracked_objects |
OLD | NEW |