| 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/field_trial.h" | 5 #include "base/metrics/field_trial.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/build_time.h" | 9 #include "base/build_time.h" |
| 10 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
| 12 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 13 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 15 | 16 |
| 16 namespace base { | 17 namespace base { |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 void CheckTrialGroup(const std::string& trial_name, | 109 void CheckTrialGroup(const std::string& trial_name, |
| 109 const std::string& trial_group, | 110 const std::string& trial_group, |
| 110 std::map<std::string, std::string>* seen_states) { | 111 std::map<std::string, std::string>* seen_states) { |
| 111 if (ContainsKey(*seen_states, trial_name)) { | 112 if (ContainsKey(*seen_states, trial_name)) { |
| 112 CHECK_EQ((*seen_states)[trial_name], trial_group) << trial_name; | 113 CHECK_EQ((*seen_states)[trial_name], trial_group) << trial_name; |
| 113 } else { | 114 } else { |
| 114 (*seen_states)[trial_name] = trial_group; | 115 (*seen_states)[trial_name] = trial_group; |
| 115 } | 116 } |
| 116 } | 117 } |
| 117 | 118 |
| 119 // A second copy of FieldTrialList::seen_states_ that is meant to outlive the |
| 120 // FieldTrialList object to determine if the inconsistency happens because there |
| 121 // might be multiple FieldTrialList objects. |
| 122 // TODO(asvitkine): Remove when crbug.com/359406 is resolved. |
| 123 base::LazyInstance<std::map<std::string, std::string>>::Leaky g_seen_states = |
| 124 LAZY_INSTANCE_INITIALIZER; |
| 125 |
| 126 // Tracks whether |g_seen_states| is used. Defaults to false, because unit tests |
| 127 // will create multiple FieldTrialList instances. |
| 128 bool g_use_global_check_states = false; |
| 129 |
| 118 } // namespace | 130 } // namespace |
| 119 | 131 |
| 120 // statics | 132 // statics |
| 121 const int FieldTrial::kNotFinalized = -1; | 133 const int FieldTrial::kNotFinalized = -1; |
| 122 const int FieldTrial::kDefaultGroupNumber = 0; | 134 const int FieldTrial::kDefaultGroupNumber = 0; |
| 123 bool FieldTrial::enable_benchmarking_ = false; | 135 bool FieldTrial::enable_benchmarking_ = false; |
| 124 | 136 |
| 125 int FieldTrialList::kNoExpirationYear = 0; | 137 int FieldTrialList::kNoExpirationYear = 0; |
| 126 | 138 |
| 127 //------------------------------------------------------------------------------ | 139 //------------------------------------------------------------------------------ |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 while (!registered_.empty()) { | 343 while (!registered_.empty()) { |
| 332 RegistrationMap::iterator it = registered_.begin(); | 344 RegistrationMap::iterator it = registered_.begin(); |
| 333 it->second->Release(); | 345 it->second->Release(); |
| 334 registered_.erase(it->first); | 346 registered_.erase(it->first); |
| 335 } | 347 } |
| 336 DCHECK_EQ(this, global_); | 348 DCHECK_EQ(this, global_); |
| 337 global_ = NULL; | 349 global_ = NULL; |
| 338 } | 350 } |
| 339 | 351 |
| 340 // static | 352 // static |
| 353 void FieldTrialList::EnableGlobalStateChecks() { |
| 354 CHECK(!g_use_global_check_states); |
| 355 g_use_global_check_states = true; |
| 356 } |
| 357 |
| 358 // static |
| 341 FieldTrial* FieldTrialList::FactoryGetFieldTrial( | 359 FieldTrial* FieldTrialList::FactoryGetFieldTrial( |
| 342 const std::string& trial_name, | 360 const std::string& trial_name, |
| 343 FieldTrial::Probability total_probability, | 361 FieldTrial::Probability total_probability, |
| 344 const std::string& default_group_name, | 362 const std::string& default_group_name, |
| 345 const int year, | 363 const int year, |
| 346 const int month, | 364 const int month, |
| 347 const int day_of_month, | 365 const int day_of_month, |
| 348 FieldTrial::RandomizationType randomization_type, | 366 FieldTrial::RandomizationType randomization_type, |
| 349 int* default_group_number) { | 367 int* default_group_number) { |
| 350 return FactoryGetFieldTrialWithRandomizationSeed( | 368 return FactoryGetFieldTrialWithRandomizationSeed( |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 trial.trial_name.find(kPersistentStringSeparator)); | 500 trial.trial_name.find(kPersistentStringSeparator)); |
| 483 DCHECK_EQ(std::string::npos, | 501 DCHECK_EQ(std::string::npos, |
| 484 trial.group_name.find(kPersistentStringSeparator)); | 502 trial.group_name.find(kPersistentStringSeparator)); |
| 485 if (trial.activated) | 503 if (trial.activated) |
| 486 output->append(1, kActivationMarker); | 504 output->append(1, kActivationMarker); |
| 487 trial.trial_name.AppendToString(output); | 505 trial.trial_name.AppendToString(output); |
| 488 output->append(1, kPersistentStringSeparator); | 506 output->append(1, kPersistentStringSeparator); |
| 489 trial.group_name.AppendToString(output); | 507 trial.group_name.AppendToString(output); |
| 490 output->append(1, kPersistentStringSeparator); | 508 output->append(1, kPersistentStringSeparator); |
| 491 | 509 |
| 510 // TODO(asvitkine): Remove these when http://crbug.com/359406 is fixed. |
| 492 CheckTrialGroup(trial.trial_name.as_string(), trial.group_name.as_string(), | 511 CheckTrialGroup(trial.trial_name.as_string(), trial.group_name.as_string(), |
| 493 &global_->seen_states_); | 512 &global_->seen_states_); |
| 513 if (g_use_global_check_states) { |
| 514 CheckTrialGroup(trial.trial_name.as_string(), |
| 515 trial.group_name.as_string(), &g_seen_states.Get()); |
| 516 } |
| 494 } | 517 } |
| 495 } | 518 } |
| 496 | 519 |
| 497 // static | 520 // static |
| 498 void FieldTrialList::GetActiveFieldTrialGroups( | 521 void FieldTrialList::GetActiveFieldTrialGroups( |
| 499 FieldTrial::ActiveGroups* active_groups) { | 522 FieldTrial::ActiveGroups* active_groups) { |
| 500 DCHECK(active_groups->empty()); | 523 DCHECK(active_groups->empty()); |
| 501 if (!global_) | 524 if (!global_) |
| 502 return; | 525 return; |
| 503 AutoLock auto_lock(global_->lock_); | 526 AutoLock auto_lock(global_->lock_); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 { | 631 { |
| 609 AutoLock auto_lock(global_->lock_); | 632 AutoLock auto_lock(global_->lock_); |
| 610 if (field_trial->group_reported_) | 633 if (field_trial->group_reported_) |
| 611 return; | 634 return; |
| 612 field_trial->group_reported_ = true; | 635 field_trial->group_reported_ = true; |
| 613 } | 636 } |
| 614 | 637 |
| 615 if (!field_trial->enable_field_trial_) | 638 if (!field_trial->enable_field_trial_) |
| 616 return; | 639 return; |
| 617 | 640 |
| 641 // TODO(asvitkine): Remove this block when http://crbug.com/359406 is fixed. |
| 618 { | 642 { |
| 619 AutoLock auto_lock(global_->lock_); | 643 AutoLock auto_lock(global_->lock_); |
| 620 CheckTrialGroup(field_trial->trial_name(), | 644 CheckTrialGroup(field_trial->trial_name(), |
| 621 field_trial->group_name_internal(), &global_->seen_states_); | 645 field_trial->group_name_internal(), &global_->seen_states_); |
| 646 if (g_use_global_check_states) { |
| 647 CheckTrialGroup(field_trial->trial_name(), |
| 648 field_trial->group_name_internal(), &g_seen_states.Get()); |
| 649 } |
| 622 } | 650 } |
| 623 global_->observer_list_->Notify( | 651 global_->observer_list_->Notify( |
| 624 FROM_HERE, &FieldTrialList::Observer::OnFieldTrialGroupFinalized, | 652 FROM_HERE, &FieldTrialList::Observer::OnFieldTrialGroupFinalized, |
| 625 field_trial->trial_name(), field_trial->group_name_internal()); | 653 field_trial->trial_name(), field_trial->group_name_internal()); |
| 626 } | 654 } |
| 627 | 655 |
| 628 // static | 656 // static |
| 629 size_t FieldTrialList::GetFieldTrialCount() { | 657 size_t FieldTrialList::GetFieldTrialCount() { |
| 630 if (!global_) | 658 if (!global_) |
| 631 return 0; | 659 return 0; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 658 return; | 686 return; |
| 659 } | 687 } |
| 660 AutoLock auto_lock(global_->lock_); | 688 AutoLock auto_lock(global_->lock_); |
| 661 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); | 689 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); |
| 662 trial->AddRef(); | 690 trial->AddRef(); |
| 663 trial->SetTrialRegistered(); | 691 trial->SetTrialRegistered(); |
| 664 global_->registered_[trial->trial_name()] = trial; | 692 global_->registered_[trial->trial_name()] = trial; |
| 665 } | 693 } |
| 666 | 694 |
| 667 } // namespace base | 695 } // namespace base |
| OLD | NEW |