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

Side by Side Diff: base/feature_list.cc

Issue 2110083007: Updating FeatureList default initialization pattern (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing a DCHECK vs. CHECK problem Created 4 years, 5 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
« no previous file with comments | « base/feature_list.h ('k') | base/feature_list_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/feature_list.h" 5 #include "base/feature_list.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 17 matching lines...) Expand all
28 // serialization. This function checks that the strings are ASCII (since they 28 // serialization. This function checks that the strings are ASCII (since they
29 // are used in command-line API functions that require ASCII) and whether there 29 // are used in command-line API functions that require ASCII) and whether there
30 // are any reserved characters present, returning true if the string is valid. 30 // are any reserved characters present, returning true if the string is valid.
31 // Only called in DCHECKs. 31 // Only called in DCHECKs.
32 bool IsValidFeatureOrFieldTrialName(const std::string& name) { 32 bool IsValidFeatureOrFieldTrialName(const std::string& name) {
33 return IsStringASCII(name) && name.find_first_of(",<*") == std::string::npos; 33 return IsStringASCII(name) && name.find_first_of(",<*") == std::string::npos;
34 } 34 }
35 35
36 } // namespace 36 } // namespace
37 37
38 FeatureList::FeatureList() 38 FeatureList::FeatureList() {}
39 : initialized_(false),
40 initialized_from_command_line_(false) {
41 }
42 39
43 FeatureList::~FeatureList() {} 40 FeatureList::~FeatureList() {}
44 41
45 void FeatureList::InitializeFromCommandLine( 42 void FeatureList::InitializeFromCommandLine(
46 const std::string& enable_features, 43 const std::string& enable_features,
47 const std::string& disable_features) { 44 const std::string& disable_features) {
48 DCHECK(!initialized_); 45 DCHECK(!initialized_);
49 46
50 // Process disabled features first, so that disabled ones take precedence over 47 // Process disabled features first, so that disabled ones take precedence over
51 // enabled ones (since RegisterOverride() uses insert()). 48 // enabled ones (since RegisterOverride() uses insert()).
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 target_list->append(entry.first); 123 target_list->append(entry.first);
127 if (entry.second.field_trial) { 124 if (entry.second.field_trial) {
128 target_list->push_back('<'); 125 target_list->push_back('<');
129 target_list->append(entry.second.field_trial->trial_name()); 126 target_list->append(entry.second.field_trial->trial_name());
130 } 127 }
131 } 128 }
132 } 129 }
133 130
134 // static 131 // static
135 bool FeatureList::IsEnabled(const Feature& feature) { 132 bool FeatureList::IsEnabled(const Feature& feature) {
133 if (!GetInstance()) {
134 CHECK(InitializeInstance(std::string(), std::string()));
Sergey Ulanov 2016/07/01 21:36:10 As discussed offline I think the problem here is t
Alexei Svitkine (slow) 2016/07/04 15:50:06 I don't think we want this class to use base::Sing
Sergey Ulanov 2016/07/04 16:52:53 base::Singleton<>::get() doesn't have any locks. I
Alexei Svitkine (slow) 2016/07/04 16:55:55 Still, that's more overhead than we have currently
joedow 2016/07/05 21:05:56 My concern with the feedback above is that I don't
Alexei Svitkine (slow) 2016/07/05 21:11:34 That's a good point. Returning default state SGTM.
135 GetInstance()->initialized_from_accessor_ = true;
136 }
136 return GetInstance()->IsFeatureEnabled(feature); 137 return GetInstance()->IsFeatureEnabled(feature);
137 } 138 }
138 139
139 // static 140 // static
140 FieldTrial* FeatureList::GetFieldTrial(const Feature& feature) { 141 FieldTrial* FeatureList::GetFieldTrial(const Feature& feature) {
142 if (!GetInstance()) {
143 CHECK(InitializeInstance(std::string(), std::string()));
144 GetInstance()->initialized_from_accessor_ = true;
145 }
141 return GetInstance()->GetAssociatedFieldTrial(feature); 146 return GetInstance()->GetAssociatedFieldTrial(feature);
142 } 147 }
143 148
144 // static 149 // static
145 std::vector<std::string> FeatureList::SplitFeatureListString( 150 std::vector<std::string> FeatureList::SplitFeatureListString(
146 const std::string& input) { 151 const std::string& input) {
147 return SplitString(input, ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); 152 return SplitString(input, ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
148 } 153 }
149 154
150 // static 155 // static
151 bool FeatureList::InitializeInstance(const std::string& enable_features, 156 bool FeatureList::InitializeInstance(const std::string& enable_features,
152 const std::string& disable_features) { 157 const std::string& disable_features) {
153 // We want to initialize a new instance here to support command-line features 158 // We want to initialize a new instance here to support command-line features
154 // in testing better. For example, we initialize a dummy instance in 159 // in testing better. For example, we initialize a dummy instance in
155 // base/test/test_suite.cc, and override it in content/browser/ 160 // base/test/test_suite.cc, and override it in content/browser/
156 // browser_main_loop.cc. 161 // browser_main_loop.cc.
157 // On the other hand, we want to avoid re-initialization from command line. 162 // On the other hand, we want to avoid re-initialization from command line.
158 // For example, we initialize an instance in chrome/browser/ 163 // For example, we initialize an instance in chrome/browser/
159 // chrome_browser_main.cc and do not override it in content/browser/ 164 // chrome_browser_main.cc and do not override it in content/browser/
160 // browser_main_loop.cc. 165 // browser_main_loop.cc.
166 // If the singleton was previously initialized from within an accessor, we
167 // want to prevent callers from reinitializing the singleton and masking the
168 // access call(s) which likely returned incorrect information.
161 bool instance_existed_before = false; 169 bool instance_existed_before = false;
162 if (g_instance) { 170 if (g_instance) {
171 DCHECK(!g_instance->initialized_from_accessor_);
163 if (g_instance->initialized_from_command_line_) 172 if (g_instance->initialized_from_command_line_)
164 return false; 173 return false;
165 174
166 delete g_instance; 175 delete g_instance;
167 g_instance = nullptr; 176 g_instance = nullptr;
168 instance_existed_before = true; 177 instance_existed_before = true;
169 } 178 }
170 179
171 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); 180 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
172 feature_list->InitializeFromCommandLine(enable_features, disable_features); 181 feature_list->InitializeFromCommandLine(enable_features, disable_features);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 return it->second == &feature; 297 return it->second == &feature;
289 } 298 }
290 299
291 FeatureList::OverrideEntry::OverrideEntry(OverrideState overridden_state, 300 FeatureList::OverrideEntry::OverrideEntry(OverrideState overridden_state,
292 FieldTrial* field_trial) 301 FieldTrial* field_trial)
293 : overridden_state(overridden_state), 302 : overridden_state(overridden_state),
294 field_trial(field_trial), 303 field_trial(field_trial),
295 overridden_by_field_trial(field_trial != nullptr) {} 304 overridden_by_field_trial(field_trial != nullptr) {}
296 305
297 } // namespace base 306 } // namespace base
OLDNEW
« no previous file with comments | « base/feature_list.h ('k') | base/feature_list_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698