| Index: base/metrics/histogram_snapshot_manager.cc
|
| diff --git a/base/metrics/histogram_snapshot_manager.cc b/base/metrics/histogram_snapshot_manager.cc
|
| index c6eb7fb82e12ccb0ce147019471ab5a80fca049f..8dccc6d7ddf7235dc36651213860fa079214fb12 100644
|
| --- a/base/metrics/histogram_snapshot_manager.cc
|
| +++ b/base/metrics/histogram_snapshot_manager.cc
|
| @@ -27,8 +27,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 &
|
| @@ -38,19 +39,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::PrepareAbsolute(const HistogramBase* histogram) {
|
| - PrepareSamples(histogram, histogram->SnapshotSamples());
|
| + PrepareSamples(histogram, histogram->SnapshotSamples(), false);
|
| +}
|
| +
|
| +void HistogramSnapshotManager::PrepareAbsoluteTakingOwnership(
|
| + 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 & HistogramBase::NEW_INCONSISTENCY_FOUND) {
|
| @@ -77,22 +92,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
|
|
|