Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: base/metrics/statistics_recorder.cc

Issue 1779503002: Fix StatisticsRecorder to handle re-entry during tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/at_exit.h" 7 #include "base/at_exit.h"
8 #include "base/debug/leak_annotations.h" 8 #include "base/debug/leak_annotations.h"
9 #include "base/json/string_escape.h" 9 #include "base/json/string_escape.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 base::AutoLock auto_lock(*lock_); 362 base::AutoLock auto_lock(*lock_);
363 if (histograms_ == NULL) 363 if (histograms_ == NULL)
364 return OnSampleCallback(); 364 return OnSampleCallback();
365 365
366 auto callback_iterator = callbacks_->find(name); 366 auto callback_iterator = callbacks_->find(name);
367 return callback_iterator != callbacks_->end() ? callback_iterator->second 367 return callback_iterator != callbacks_->end() ? callback_iterator->second
368 : OnSampleCallback(); 368 : OnSampleCallback();
369 } 369 }
370 370
371 // static 371 // static
372 void StatisticsRecorder::ResetForTesting() {
373 // Just call the private version that is used also by the destructor.
374 Reset();
375 }
376
377 // static
378 void StatisticsRecorder::ForgetHistogramForTesting(base::StringPiece name) { 372 void StatisticsRecorder::ForgetHistogramForTesting(base::StringPiece name) {
379 if (histograms_) 373 if (histograms_)
380 histograms_->erase(HashMetricName(name.as_string())); 374 histograms_->erase(HashMetricName(name.as_string()));
381 } 375 }
382 376
383 // This singleton instance should be started during the single threaded portion 377 // This singleton instance should be started during the single threaded portion
384 // of main(), and hence it is not thread safe. It initializes globals to 378 // of main(), and hence it is not thread safe. It initializes globals to
385 // provide support for all future calls. 379 // provide support for all future calls.
386 StatisticsRecorder::StatisticsRecorder() { 380 StatisticsRecorder::StatisticsRecorder() {
387 DCHECK(!histograms_);
388 if (lock_ == NULL) { 381 if (lock_ == NULL) {
389 // This will leak on purpose. It's the only way to make sure we won't race 382 // This will leak on purpose. It's the only way to make sure we won't race
390 // against the static uninitialization of the module while one of our 383 // against the static uninitialization of the module while one of our
391 // static methods relying on the lock get called at an inappropriate time 384 // static methods relying on the lock get called at an inappropriate time
392 // during the termination phase. Since it's a static data member, we will 385 // during the termination phase. Since it's a static data member, we will
393 // leak one per process, which would be similar to the instance allocated 386 // leak one per process, which would be similar to the instance allocated
394 // during static initialization and released only on process termination. 387 // during static initialization and released only on process termination.
395 lock_ = new base::Lock; 388 lock_ = new base::Lock;
396 } 389 }
390
397 base::AutoLock auto_lock(*lock_); 391 base::AutoLock auto_lock(*lock_);
392
393 existing_histograms_.reset(histograms_);
394 existing_callbacks_.reset(callbacks_);
395 existing_ranges_.reset(ranges_);
396
398 histograms_ = new HistogramMap; 397 histograms_ = new HistogramMap;
399 callbacks_ = new CallbackMap; 398 callbacks_ = new CallbackMap;
400 ranges_ = new RangesMap; 399 ranges_ = new RangesMap;
401 400
402 if (VLOG_IS_ON(1)) 401 if (VLOG_IS_ON(1))
403 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this); 402 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this);
404 } 403 }
405 404
406 StatisticsRecorder::~StatisticsRecorder() { 405 StatisticsRecorder::~StatisticsRecorder() {
407 DCHECK(histograms_ && ranges_ && lock_); 406 DCHECK(histograms_ && ranges_ && lock_);
408 407
409 // Global clean up. 408 // Clean out what this object created and then restore what existed before.
410 Reset(); 409 Reset();
410 base::AutoLock auto_lock(*lock_);
411 histograms_ = existing_histograms_.release();
412 callbacks_ = existing_callbacks_.release();
413 ranges_ = existing_ranges_.release();
411 } 414 }
412 415
413 // static 416 // static
414 void StatisticsRecorder::Reset() { 417 void StatisticsRecorder::Reset() {
415 // If there's no lock then there is nothing to reset. 418 // If there's no lock then there is nothing to reset.
416 if (!lock_) 419 if (!lock_)
417 return; 420 return;
418 421
419 scoped_ptr<HistogramMap> histograms_deleter; 422 scoped_ptr<HistogramMap> histograms_deleter;
420 scoped_ptr<CallbackMap> callbacks_deleter; 423 scoped_ptr<CallbackMap> callbacks_deleter;
(...skipping 23 matching lines...) Expand all
444 // static 447 // static
445 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; 448 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
446 // static 449 // static
447 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL; 450 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL;
448 // static 451 // static
449 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; 452 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
450 // static 453 // static
451 base::Lock* StatisticsRecorder::lock_ = NULL; 454 base::Lock* StatisticsRecorder::lock_ = NULL;
452 455
453 } // namespace base 456 } // namespace base
OLDNEW
« base/metrics/statistics_recorder.h ('K') | « base/metrics/statistics_recorder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698