| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/metrics/statistics_recorder.h" | 5 #include "base/metrics/statistics_recorder.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/debug/leak_annotations.h" | 10 #include "base/debug/leak_annotations.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 } | 67 } |
| 68 | 68 |
| 69 return *this; | 69 return *this; |
| 70 } | 70 } |
| 71 | 71 |
| 72 StatisticsRecorder::~StatisticsRecorder() { | 72 StatisticsRecorder::~StatisticsRecorder() { |
| 73 DCHECK(lock_); | 73 DCHECK(lock_); |
| 74 DCHECK(histograms_); | 74 DCHECK(histograms_); |
| 75 DCHECK(ranges_); | 75 DCHECK(ranges_); |
| 76 | 76 |
| 77 // Global clean up. | 77 // Clean out what this object created and then restore what existed before. |
| 78 Reset(); | 78 Reset(); |
| 79 base::AutoLock auto_lock(*lock_); |
| 80 histograms_ = existing_histograms_.release(); |
| 81 callbacks_ = existing_callbacks_.release(); |
| 82 ranges_ = existing_ranges_.release(); |
| 79 } | 83 } |
| 80 | 84 |
| 81 // static | 85 // static |
| 82 void StatisticsRecorder::Initialize() { | 86 void StatisticsRecorder::Initialize() { |
| 83 // Ensure that an instance of the StatisticsRecorder object is created. | 87 // Ensure that an instance of the StatisticsRecorder object is created. |
| 84 g_statistics_recorder_.Get(); | 88 g_statistics_recorder_.Get(); |
| 85 } | 89 } |
| 86 | 90 |
| 87 // static | 91 // static |
| 88 bool StatisticsRecorder::IsActive() { | 92 bool StatisticsRecorder::IsActive() { |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 if (!lock_) | 390 if (!lock_) |
| 387 return 0; | 391 return 0; |
| 388 | 392 |
| 389 base::AutoLock auto_lock(*lock_); | 393 base::AutoLock auto_lock(*lock_); |
| 390 if (!histograms_) | 394 if (!histograms_) |
| 391 return 0; | 395 return 0; |
| 392 return histograms_->size(); | 396 return histograms_->size(); |
| 393 } | 397 } |
| 394 | 398 |
| 395 // static | 399 // static |
| 396 void StatisticsRecorder::ResetForTesting() { | |
| 397 // Just call the private version that is used also by the destructor. | |
| 398 Reset(); | |
| 399 } | |
| 400 | |
| 401 // static | |
| 402 void StatisticsRecorder::ForgetHistogramForTesting(base::StringPiece name) { | 400 void StatisticsRecorder::ForgetHistogramForTesting(base::StringPiece name) { |
| 403 if (histograms_) | 401 if (histograms_) |
| 404 histograms_->erase(name); | 402 histograms_->erase(name); |
| 405 } | 403 } |
| 406 | 404 |
| 405 // static |
| 406 void StatisticsRecorder::UninitializeForTesting() { |
| 407 // Stop now if it's never been initialized. |
| 408 if (lock_ == NULL || histograms_ == NULL) |
| 409 return; |
| 410 |
| 411 // Get the global instance and destruct it. It's held in static memory so |
| 412 // can't "delete" it; call the destructor explicitly. |
| 413 DCHECK(g_statistics_recorder_.private_instance_); |
| 414 g_statistics_recorder_.Get().~StatisticsRecorder(); |
| 415 |
| 416 // Now the ugly part. There's no official way to release a LazyInstance once |
| 417 // created so it's necessary to clear out an internal variable which |
| 418 // shouldn't be publicly visible but is for initialization reasons. |
| 419 g_statistics_recorder_.private_instance_ = 0; |
| 420 } |
| 421 |
| 407 // This singleton instance should be started during the single threaded portion | 422 // This singleton instance should be started during the single threaded portion |
| 408 // of main(), and hence it is not thread safe. It initializes globals to | 423 // of main(), and hence it is not thread safe. It initializes globals to |
| 409 // provide support for all future calls. | 424 // provide support for all future calls. |
| 410 StatisticsRecorder::StatisticsRecorder() { | 425 StatisticsRecorder::StatisticsRecorder() { |
| 411 DCHECK(!histograms_); | |
| 412 if (lock_ == NULL) { | 426 if (lock_ == NULL) { |
| 413 // This will leak on purpose. It's the only way to make sure we won't race | 427 // This will leak on purpose. It's the only way to make sure we won't race |
| 414 // against the static uninitialization of the module while one of our | 428 // against the static uninitialization of the module while one of our |
| 415 // static methods relying on the lock get called at an inappropriate time | 429 // static methods relying on the lock get called at an inappropriate time |
| 416 // during the termination phase. Since it's a static data member, we will | 430 // during the termination phase. Since it's a static data member, we will |
| 417 // leak one per process, which would be similar to the instance allocated | 431 // leak one per process, which would be similar to the instance allocated |
| 418 // during static initialization and released only on process termination. | 432 // during static initialization and released only on process termination. |
| 419 lock_ = new base::Lock; | 433 lock_ = new base::Lock; |
| 420 } | 434 } |
| 435 |
| 421 base::AutoLock auto_lock(*lock_); | 436 base::AutoLock auto_lock(*lock_); |
| 437 |
| 438 existing_histograms_.reset(histograms_); |
| 439 existing_callbacks_.reset(callbacks_); |
| 440 existing_ranges_.reset(ranges_); |
| 441 |
| 422 histograms_ = new HistogramMap; | 442 histograms_ = new HistogramMap; |
| 423 callbacks_ = new CallbackMap; | 443 callbacks_ = new CallbackMap; |
| 424 ranges_ = new RangesMap; | 444 ranges_ = new RangesMap; |
| 425 | 445 |
| 426 if (VLOG_IS_ON(1)) | 446 if (VLOG_IS_ON(1)) |
| 427 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this); | 447 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this); |
| 428 } | 448 } |
| 429 | 449 |
| 430 // static | 450 // static |
| 431 void StatisticsRecorder::Reset() { | 451 void StatisticsRecorder::Reset() { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 461 // static | 481 // static |
| 462 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; | 482 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; |
| 463 // static | 483 // static |
| 464 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL; | 484 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL; |
| 465 // static | 485 // static |
| 466 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; | 486 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; |
| 467 // static | 487 // static |
| 468 base::Lock* StatisticsRecorder::lock_ = NULL; | 488 base::Lock* StatisticsRecorder::lock_ = NULL; |
| 469 | 489 |
| 470 } // namespace base | 490 } // namespace base |
| OLD | NEW |