Index: base/metrics/histogram_snapshot_manager.cc |
diff --git a/base/metrics/histogram_snapshot_manager.cc b/base/metrics/histogram_snapshot_manager.cc |
index 4783462e7535ea841b9899630529a086603759db..e3cc84347ed4a9ddc4f8a2342cf9ebb60ee517ec 100644 |
--- a/base/metrics/histogram_snapshot_manager.cc |
+++ b/base/metrics/histogram_snapshot_manager.cc |
@@ -11,9 +11,7 @@ |
#include "base/stl_util.h" |
namespace { |
-// A flag to indicate that a new inconsistency has been added to the set. |
-// It is used to know if the value needs to be sent upstream and cleared after. |
-const int kNewInconsistency = (int)0x80000000; |
+const int kNewInconsistency = static_cast<int>(0x80000000); |
} // namespace |
namespace base { |
@@ -33,8 +31,9 @@ void HistogramSnapshotManager::StartDeltas() { |
DCHECK(!preparing_deltas_); |
preparing_deltas_ = true; |
+ DCHECK(owned_histograms_.empty()); |
+ |
#ifdef DEBUG |
- for (const auto& iter : known_histograms) { |
CHECK(!iter->second.histogram); |
CHECK(!iter->second.accumulated_samples); |
CHECK(!(iter->second.inconsistencies & kNewInconsistency)); |
@@ -43,19 +42,33 @@ void HistogramSnapshotManager::StartDeltas() { |
} |
void HistogramSnapshotManager::PrepareDelta(HistogramBase* histogram) { |
- PrepareSamples(histogram, histogram->SnapshotDelta()); |
+ PrepareSamples(histogram, histogram->SnapshotDelta(), false); |
+} |
+ |
+void HistogramSnapshotManager::PrepareDeltaTakingOwnership( |
+ scoped_ptr<HistogramBase> histogram) { |
+ // Snapshot must be done before releasing the pointer. |
+ scoped_ptr<HistogramSamples> samples = histogram->SnapshotDelta(); |
+ PrepareSamples(histogram.release(), std::move(samples), true); |
} |
void HistogramSnapshotManager::PrepareOnce(const HistogramBase* histogram) { |
- PrepareSamples(histogram, histogram->SnapshotSamples()); |
+ PrepareSamples(histogram, histogram->SnapshotSamples(), false); |
+} |
+ |
+void HistogramSnapshotManager::PrepareOnceTakingOwnership( |
+ scoped_ptr<const HistogramBase> histogram) { |
+ // Snapshot must be done before releasing the pointer. |
+ scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples(); |
+ PrepareSamples(histogram.release(), std::move(samples), true); |
} |
void HistogramSnapshotManager::FinishDeltas() { |
DCHECK(preparing_deltas_); |
// Iterate over all known histograms to see what should be recorded. |
- for (auto& iter : known_histograms_) { |
- SampleInfo* sample_info = &iter.second; |
+ for (auto& hash_and_info : known_histograms_) { |
+ SampleInfo* sample_info = &hash_and_info.second; |
// First, record any histograms in which corruption was detected. |
if (sample_info->inconsistencies & kNewInconsistency) { |
@@ -82,22 +95,33 @@ void HistogramSnapshotManager::FinishDeltas() { |
sample_info->histogram = nullptr; |
} |
+ owned_histograms_.clear(); |
preparing_deltas_ = false; |
} |
void HistogramSnapshotManager::PrepareSamples( |
const HistogramBase* histogram, |
- scoped_ptr<HistogramSamples> samples) { |
+ scoped_ptr<HistogramSamples> samples, |
+ bool take_ownership) { |
DCHECK(histogram_flattener_); |
+ scoped_ptr<const HistogramBase> owned_histogram; |
// Get information known about this histogram. |
SampleInfo* sample_info = &known_histograms_[histogram->name_hash()]; |
if (sample_info->histogram) { |
DCHECK_EQ(sample_info->histogram->histogram_name(), |
histogram->histogram_name()) << "hash collision"; |
+ // Passed histogram won't be needed past end of this method so store |
+ // it in a scoped_ptr that will release it when returning. |
+ if (take_ownership) |
+ owned_histogram.reset(histogram); |
} else { |
// First time this histogram has been seen; datafill. |
sample_info->histogram = histogram; |
+ // The histogram data will be needed up until "finished" so store |
+ // in member vector for releasing when that is done. |
+ if (take_ownership) |
+ owned_histograms_.push_back(make_scoped_ptr(histogram)); |
} |
// Crash if we detect that our histograms have been overwritten. This may be |