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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 |
492 CheckTrialGroup(trial.trial_name.as_string(), trial.group_name.as_string(), | 510 CheckTrialGroup(trial.trial_name.as_string(), trial.group_name.as_string(), |
493 &global_->seen_states_); | 511 &global_->seen_states_); |
512 if (g_use_global_check_states) { | |
513 CheckTrialGroup(trial.trial_name.as_string(), | |
514 trial.group_name.as_string(), &g_seen_states.Get()); | |
515 } | |
494 } | 516 } |
495 } | 517 } |
496 | 518 |
497 // static | 519 // static |
498 void FieldTrialList::GetActiveFieldTrialGroups( | 520 void FieldTrialList::GetActiveFieldTrialGroups( |
499 FieldTrial::ActiveGroups* active_groups) { | 521 FieldTrial::ActiveGroups* active_groups) { |
500 DCHECK(active_groups->empty()); | 522 DCHECK(active_groups->empty()); |
501 if (!global_) | 523 if (!global_) |
502 return; | 524 return; |
503 AutoLock auto_lock(global_->lock_); | 525 AutoLock auto_lock(global_->lock_); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
612 field_trial->group_reported_ = true; | 634 field_trial->group_reported_ = true; |
613 } | 635 } |
614 | 636 |
615 if (!field_trial->enable_field_trial_) | 637 if (!field_trial->enable_field_trial_) |
616 return; | 638 return; |
617 | 639 |
618 { | 640 { |
619 AutoLock auto_lock(global_->lock_); | 641 AutoLock auto_lock(global_->lock_); |
620 CheckTrialGroup(field_trial->trial_name(), | 642 CheckTrialGroup(field_trial->trial_name(), |
621 field_trial->group_name_internal(), &global_->seen_states_); | 643 field_trial->group_name_internal(), &global_->seen_states_); |
644 if (g_use_global_check_states) { | |
Nico
2016/04/15 19:00:31
should this block have a comment too?
Alexei Svitkine (slow)
2016/04/15 20:28:45
Done.
| |
645 CheckTrialGroup(field_trial->trial_name(), | |
646 field_trial->group_name_internal(), &g_seen_states.Get()); | |
647 } | |
622 } | 648 } |
623 global_->observer_list_->Notify( | 649 global_->observer_list_->Notify( |
624 FROM_HERE, &FieldTrialList::Observer::OnFieldTrialGroupFinalized, | 650 FROM_HERE, &FieldTrialList::Observer::OnFieldTrialGroupFinalized, |
625 field_trial->trial_name(), field_trial->group_name_internal()); | 651 field_trial->trial_name(), field_trial->group_name_internal()); |
626 } | 652 } |
627 | 653 |
628 // static | 654 // static |
629 size_t FieldTrialList::GetFieldTrialCount() { | 655 size_t FieldTrialList::GetFieldTrialCount() { |
630 if (!global_) | 656 if (!global_) |
631 return 0; | 657 return 0; |
(...skipping 26 matching lines...) Expand all Loading... | |
658 return; | 684 return; |
659 } | 685 } |
660 AutoLock auto_lock(global_->lock_); | 686 AutoLock auto_lock(global_->lock_); |
661 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); | 687 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); |
662 trial->AddRef(); | 688 trial->AddRef(); |
663 trial->SetTrialRegistered(); | 689 trial->SetTrialRegistered(); |
664 global_->registered_[trial->trial_name()] = trial; | 690 global_->registered_[trial->trial_name()] = trial; |
665 } | 691 } |
666 | 692 |
667 } // namespace base | 693 } // namespace base |
OLD | NEW |