| Index: base/metrics/statistics_recorder.cc
|
| diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
|
| index 6b1b0bfdea211e152e30929cac8216479a09786b..482845045f2bfcf08596846aabb032c277b0f048 100644
|
| --- a/base/metrics/statistics_recorder.cc
|
| +++ b/base/metrics/statistics_recorder.cc
|
| @@ -16,7 +16,6 @@
|
| #include "base/metrics/persistent_histogram_allocator.h"
|
| #include "base/stl_util.h"
|
| #include "base/strings/stringprintf.h"
|
| -#include "base/synchronization/lock.h"
|
| #include "base/values.h"
|
|
|
| namespace {
|
| @@ -59,10 +58,10 @@ StatisticsRecorder::HistogramIterator::~HistogramIterator() {}
|
| StatisticsRecorder::HistogramIterator&
|
| StatisticsRecorder::HistogramIterator::operator++() {
|
| const HistogramMap::iterator histograms_end = histograms_->end();
|
| - if (iter_ == histograms_end || lock_ == NULL)
|
| + if (iter_ == histograms_end)
|
| return *this;
|
|
|
| - base::AutoLock auto_lock(*lock_);
|
| + base::AutoLock auto_lock(lock_.Get());
|
|
|
| for (;;) {
|
| ++iter_;
|
| @@ -79,13 +78,12 @@ StatisticsRecorder::HistogramIterator::operator++() {
|
| }
|
|
|
| StatisticsRecorder::~StatisticsRecorder() {
|
| - DCHECK(lock_);
|
| DCHECK(histograms_);
|
| DCHECK(ranges_);
|
|
|
| // Clean out what this object created and then restore what existed before.
|
| Reset();
|
| - base::AutoLock auto_lock(*lock_);
|
| + base::AutoLock auto_lock(lock_.Get());
|
| histograms_ = existing_histograms_.release();
|
| callbacks_ = existing_callbacks_.release();
|
| ranges_ = existing_ranges_.release();
|
| @@ -110,31 +108,26 @@ void StatisticsRecorder::Initialize() {
|
|
|
| // static
|
| bool StatisticsRecorder::IsActive() {
|
| - if (lock_ == NULL)
|
| - return false;
|
| - base::AutoLock auto_lock(*lock_);
|
| - return NULL != histograms_;
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + return histograms_ != nullptr;
|
| }
|
|
|
| // static
|
| HistogramBase* StatisticsRecorder::RegisterOrDeleteDuplicate(
|
| HistogramBase* histogram) {
|
| - // As per crbug.com/79322 the histograms are intentionally leaked, so we need
|
| - // to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used only once
|
| - // for an object, the duplicates should not be annotated.
|
| - // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr)
|
| - // twice if (lock_ == NULL) || (!histograms_).
|
| - if (lock_ == NULL) {
|
| - ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
|
| - return histogram;
|
| - }
|
| -
|
| - HistogramBase* histogram_to_delete = NULL;
|
| - HistogramBase* histogram_to_return = NULL;
|
| + HistogramBase* histogram_to_delete = nullptr;
|
| + HistogramBase* histogram_to_return = nullptr;
|
| {
|
| - base::AutoLock auto_lock(*lock_);
|
| - if (histograms_ == NULL) {
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + if (!histograms_) {
|
| histogram_to_return = histogram;
|
| +
|
| + // As per crbug.com/79322 the histograms are intentionally leaked, so we
|
| + // need to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used
|
| + // only once for an object, the duplicates should not be annotated.
|
| + // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr)
|
| + // twice |if (!histograms_)|.
|
| + ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
|
| } else {
|
| const std::string& name = histogram->histogram_name();
|
| HistogramMap::iterator it = histograms_->find(name);
|
| @@ -175,13 +168,8 @@ const BucketRanges* StatisticsRecorder::RegisterOrDeleteDuplicateRanges(
|
| DCHECK(ranges->HasValidChecksum());
|
| std::unique_ptr<const BucketRanges> ranges_deleter;
|
|
|
| - if (lock_ == NULL) {
|
| - ANNOTATE_LEAKING_OBJECT_PTR(ranges);
|
| - return ranges;
|
| - }
|
| -
|
| - base::AutoLock auto_lock(*lock_);
|
| - if (ranges_ == NULL) {
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + if (!ranges_) {
|
| ANNOTATE_LEAKING_OBJECT_PTR(ranges);
|
| return ranges;
|
| }
|
| @@ -278,10 +266,8 @@ std::string StatisticsRecorder::ToJSON(const std::string& query) {
|
|
|
| // static
|
| void StatisticsRecorder::GetHistograms(Histograms* output) {
|
| - if (lock_ == NULL)
|
| - return;
|
| - base::AutoLock auto_lock(*lock_);
|
| - if (histograms_ == NULL)
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + if (!histograms_)
|
| return;
|
|
|
| for (const auto& entry : *histograms_) {
|
| @@ -292,10 +278,8 @@ void StatisticsRecorder::GetHistograms(Histograms* output) {
|
| // static
|
| void StatisticsRecorder::GetBucketRanges(
|
| std::vector<const BucketRanges*>* output) {
|
| - if (lock_ == NULL)
|
| - return;
|
| - base::AutoLock auto_lock(*lock_);
|
| - if (ranges_ == NULL)
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + if (!ranges_)
|
| return;
|
|
|
| for (const auto& entry : *ranges_) {
|
| @@ -312,15 +296,13 @@ HistogramBase* StatisticsRecorder::FindHistogram(base::StringPiece name) {
|
| // will acquire the lock at that time.
|
| ImportGlobalPersistentHistograms();
|
|
|
| - if (lock_ == NULL)
|
| - return NULL;
|
| - base::AutoLock auto_lock(*lock_);
|
| - if (histograms_ == NULL)
|
| - return NULL;
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + if (!histograms_)
|
| + return nullptr;
|
|
|
| HistogramMap::iterator it = histograms_->find(name);
|
| if (histograms_->end() == it)
|
| - return NULL;
|
| + return nullptr;
|
| return it->second;
|
| }
|
|
|
| @@ -332,7 +314,7 @@ StatisticsRecorder::HistogramIterator StatisticsRecorder::begin(
|
|
|
| HistogramMap::iterator iter_begin;
|
| {
|
| - base::AutoLock auto_lock(*lock_);
|
| + base::AutoLock auto_lock(lock_.Get());
|
| iter_begin = histograms_->begin();
|
| }
|
| return HistogramIterator(iter_begin, include_persistent);
|
| @@ -342,7 +324,7 @@ StatisticsRecorder::HistogramIterator StatisticsRecorder::begin(
|
| StatisticsRecorder::HistogramIterator StatisticsRecorder::end() {
|
| HistogramMap::iterator iter_end;
|
| {
|
| - base::AutoLock auto_lock(*lock_);
|
| + base::AutoLock auto_lock(lock_.Get());
|
| iter_end = histograms_->end();
|
| }
|
| return HistogramIterator(iter_end, true);
|
| @@ -350,19 +332,18 @@ StatisticsRecorder::HistogramIterator StatisticsRecorder::end() {
|
|
|
| // static
|
| void StatisticsRecorder::InitLogOnShutdown() {
|
| - if (lock_ == nullptr)
|
| + if (!histograms_)
|
| return;
|
| - base::AutoLock auto_lock(*lock_);
|
| +
|
| + base::AutoLock auto_lock(lock_.Get());
|
| g_statistics_recorder_.Get().InitLogOnShutdownWithoutLock();
|
| }
|
|
|
| // static
|
| void StatisticsRecorder::GetSnapshot(const std::string& query,
|
| Histograms* snapshot) {
|
| - if (lock_ == NULL)
|
| - return;
|
| - base::AutoLock auto_lock(*lock_);
|
| - if (histograms_ == NULL)
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + if (!histograms_)
|
| return;
|
|
|
| for (const auto& entry : *histograms_) {
|
| @@ -376,10 +357,8 @@ bool StatisticsRecorder::SetCallback(
|
| const std::string& name,
|
| const StatisticsRecorder::OnSampleCallback& cb) {
|
| DCHECK(!cb.is_null());
|
| - if (lock_ == NULL)
|
| - return false;
|
| - base::AutoLock auto_lock(*lock_);
|
| - if (histograms_ == NULL)
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + if (!histograms_)
|
| return false;
|
|
|
| if (ContainsKey(*callbacks_, name))
|
| @@ -395,10 +374,8 @@ bool StatisticsRecorder::SetCallback(
|
|
|
| // static
|
| void StatisticsRecorder::ClearCallback(const std::string& name) {
|
| - if (lock_ == NULL)
|
| - return;
|
| - base::AutoLock auto_lock(*lock_);
|
| - if (histograms_ == NULL)
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + if (!histograms_)
|
| return;
|
|
|
| callbacks_->erase(name);
|
| @@ -412,10 +389,8 @@ void StatisticsRecorder::ClearCallback(const std::string& name) {
|
| // static
|
| StatisticsRecorder::OnSampleCallback StatisticsRecorder::FindCallback(
|
| const std::string& name) {
|
| - if (lock_ == NULL)
|
| - return OnSampleCallback();
|
| - base::AutoLock auto_lock(*lock_);
|
| - if (histograms_ == NULL)
|
| + base::AutoLock auto_lock(lock_.Get());
|
| + if (!histograms_)
|
| return OnSampleCallback();
|
|
|
| auto callback_iterator = callbacks_->find(name);
|
| @@ -425,10 +400,7 @@ StatisticsRecorder::OnSampleCallback StatisticsRecorder::FindCallback(
|
|
|
| // static
|
| size_t StatisticsRecorder::GetHistogramCount() {
|
| - if (!lock_)
|
| - return 0;
|
| -
|
| - base::AutoLock auto_lock(*lock_);
|
| + base::AutoLock auto_lock(lock_.Get());
|
| if (!histograms_)
|
| return 0;
|
| return histograms_->size();
|
| @@ -449,7 +421,7 @@ StatisticsRecorder::CreateTemporaryForTesting() {
|
| // static
|
| void StatisticsRecorder::UninitializeForTesting() {
|
| // Stop now if it's never been initialized.
|
| - if (lock_ == NULL || histograms_ == NULL)
|
| + if (!histograms_)
|
| return;
|
|
|
| // Get the global instance and destruct it. It's held in static memory so
|
| @@ -465,7 +437,7 @@ void StatisticsRecorder::UninitializeForTesting() {
|
|
|
| // static
|
| void StatisticsRecorder::ImportGlobalPersistentHistograms() {
|
| - if (lock_ == NULL)
|
| + if (!histograms_)
|
| return;
|
|
|
| // Import histograms from known persistent storage. Histograms could have
|
| @@ -481,17 +453,7 @@ void StatisticsRecorder::ImportGlobalPersistentHistograms() {
|
| // of main(), and hence it is not thread safe. It initializes globals to
|
| // provide support for all future calls.
|
| StatisticsRecorder::StatisticsRecorder() {
|
| - if (lock_ == NULL) {
|
| - // This will leak on purpose. It's the only way to make sure we won't race
|
| - // against the static uninitialization of the module while one of our
|
| - // static methods relying on the lock get called at an inappropriate time
|
| - // during the termination phase. Since it's a static data member, we will
|
| - // leak one per process, which would be similar to the instance allocated
|
| - // during static initialization and released only on process termination.
|
| - lock_ = new base::Lock;
|
| - }
|
| -
|
| - base::AutoLock auto_lock(*lock_);
|
| + base::AutoLock auto_lock(lock_.Get());
|
|
|
| existing_histograms_.reset(histograms_);
|
| existing_callbacks_.reset(callbacks_);
|
| @@ -513,23 +475,18 @@ void StatisticsRecorder::InitLogOnShutdownWithoutLock() {
|
|
|
| // static
|
| void StatisticsRecorder::Reset() {
|
| - // If there's no lock then there is nothing to reset.
|
| - if (!lock_)
|
| - return;
|
|
|
| std::unique_ptr<HistogramMap> histograms_deleter;
|
| std::unique_ptr<CallbackMap> callbacks_deleter;
|
| std::unique_ptr<RangesMap> ranges_deleter;
|
| - // We don't delete lock_ on purpose to avoid having to properly protect
|
| - // against it going away after we checked for NULL in the static methods.
|
| {
|
| - base::AutoLock auto_lock(*lock_);
|
| + base::AutoLock auto_lock(lock_.Get());
|
| histograms_deleter.reset(histograms_);
|
| callbacks_deleter.reset(callbacks_);
|
| ranges_deleter.reset(ranges_);
|
| - histograms_ = NULL;
|
| - callbacks_ = NULL;
|
| - ranges_ = NULL;
|
| + histograms_ = nullptr;
|
| + callbacks_ = nullptr;
|
| + ranges_ = nullptr;
|
| }
|
| // We are going to leak the histograms and the ranges.
|
| }
|
| @@ -543,12 +500,13 @@ void StatisticsRecorder::DumpHistogramsToVlog(void* instance) {
|
|
|
|
|
| // static
|
| -StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
|
| +StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = nullptr;
|
| // static
|
| -StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL;
|
| +StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr;
|
| // static
|
| -StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
|
| +StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr;
|
| // static
|
| -base::Lock* StatisticsRecorder::lock_ = NULL;
|
| +base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ =
|
| + LAZY_INSTANCE_INITIALIZER;
|
|
|
| } // namespace base
|
|
|