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

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

Issue 2862123002: Pass the GUID for the SharedMemoryHandle used by base::FieldTrialList. (Closed)
Patch Set: Pass string piece by value. Created 3 years, 7 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/metrics/field_trial.h ('k') | base/metrics/field_trial_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 (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 #include <utility> 8 #include <utility>
9 9
10 #include "base/base_switches.h" 10 #include "base/base_switches.h"
11 #include "base/build_time.h" 11 #include "base/build_time.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/debug/activity_tracker.h" 13 #include "base/debug/activity_tracker.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/metrics/field_trial_param_associator.h" 15 #include "base/metrics/field_trial_param_associator.h"
16 #include "base/process/memory.h" 16 #include "base/process/memory.h"
17 #include "base/rand_util.h" 17 #include "base/rand_util.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_split.h"
19 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
20 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
21 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
22 #include "base/unguessable_token.h" 23 #include "base/unguessable_token.h"
23 24
24 // On POSIX, the fd is shared using the mapping in GlobalDescriptors. 25 // On POSIX, the fd is shared using the mapping in GlobalDescriptors.
25 #if defined(OS_POSIX) && !defined(OS_NACL) 26 #if defined(OS_POSIX) && !defined(OS_NACL)
26 #include "base/posix/global_descriptors.h" 27 #include "base/posix/global_descriptors.h"
27 #endif 28 #endif
28 29
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 cmd_line->AppendSwitchASCII(disable_features_switch, disabled_features); 202 cmd_line->AppendSwitchASCII(disable_features_switch, disabled_features);
202 203
203 std::string field_trial_states; 204 std::string field_trial_states;
204 FieldTrialList::AllStatesToString(&field_trial_states); 205 FieldTrialList::AllStatesToString(&field_trial_states);
205 if (!field_trial_states.empty()) { 206 if (!field_trial_states.empty()) {
206 cmd_line->AppendSwitchASCII(switches::kForceFieldTrials, 207 cmd_line->AppendSwitchASCII(switches::kForceFieldTrials,
207 field_trial_states); 208 field_trial_states);
208 } 209 }
209 } 210 }
210 211
211 #if defined(OS_WIN)
212 HANDLE CreateReadOnlyHandle(FieldTrialList::FieldTrialAllocator* allocator) {
213 HANDLE src = allocator->shared_memory()->handle().GetHandle();
214 ProcessHandle process = GetCurrentProcess();
215 DWORD access = SECTION_MAP_READ | SECTION_QUERY;
216 HANDLE dst;
217 if (!::DuplicateHandle(process, src, process, &dst, access, true, 0))
218 return kInvalidPlatformFile;
219 return dst;
220 }
221 #endif
222
223 #if defined(OS_POSIX) && !defined(OS_NACL)
224 int CreateReadOnlyHandle(FieldTrialList::FieldTrialAllocator* allocator) {
225 SharedMemoryHandle handle = allocator->shared_memory()->GetReadOnlyHandle();
226 return SharedMemory::GetFdFromSharedMemoryHandle(handle);
227 }
228 #endif
229
230 void OnOutOfMemory(size_t size) { 212 void OnOutOfMemory(size_t size) {
231 #if defined(OS_NACL) 213 #if defined(OS_NACL)
232 NOTREACHED(); 214 NOTREACHED();
233 #else 215 #else
234 TerminateBecauseOutOfMemory(size); 216 TerminateBecauseOutOfMemory(size);
235 #endif 217 #endif
236 } 218 }
237 219
220 #if !defined(OS_NACL)
221 // Returns whether the operation succeeded.
222 bool DeserializeGUIDFromStringPieces(base::StringPiece first,
223 base::StringPiece second,
224 base::UnguessableToken* guid) {
225 uint64_t high = 0;
226 uint64_t low = 0;
227 if (!base::StringToUint64(first, &high) ||
228 !base::StringToUint64(second, &low)) {
229 return false;
230 }
231
232 *guid = base::UnguessableToken::Deserialize(high, low);
233 return true;
234 }
235 #endif
236
238 } // namespace 237 } // namespace
239 238
240 // statics 239 // statics
241 const int FieldTrial::kNotFinalized = -1; 240 const int FieldTrial::kNotFinalized = -1;
242 const int FieldTrial::kDefaultGroupNumber = 0; 241 const int FieldTrial::kDefaultGroupNumber = 0;
243 bool FieldTrial::enable_benchmarking_ = false; 242 bool FieldTrial::enable_benchmarking_ = false;
244 243
245 int FieldTrialList::kNoExpirationYear = 0; 244 int FieldTrialList::kNoExpirationYear = 0;
246 245
247 //------------------------------------------------------------------------------ 246 //------------------------------------------------------------------------------
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 773
775 // static 774 // static
776 void FieldTrialList::CreateTrialsFromCommandLine( 775 void FieldTrialList::CreateTrialsFromCommandLine(
777 const CommandLine& cmd_line, 776 const CommandLine& cmd_line,
778 const char* field_trial_handle_switch, 777 const char* field_trial_handle_switch,
779 int fd_key) { 778 int fd_key) {
780 global_->create_trials_from_command_line_called_ = true; 779 global_->create_trials_from_command_line_called_ = true;
781 780
782 #if defined(OS_WIN) 781 #if defined(OS_WIN)
783 if (cmd_line.HasSwitch(field_trial_handle_switch)) { 782 if (cmd_line.HasSwitch(field_trial_handle_switch)) {
784 std::string handle_switch = 783 std::string switch_value =
785 cmd_line.GetSwitchValueASCII(field_trial_handle_switch); 784 cmd_line.GetSwitchValueASCII(field_trial_handle_switch);
786 bool result = CreateTrialsFromHandleSwitch(handle_switch); 785 bool result = CreateTrialsFromSwitchValue(switch_value);
787 DCHECK(result); 786 DCHECK(result);
788 } 787 }
789 #endif 788 #endif
790 789
791 #if defined(OS_POSIX) && !defined(OS_NACL) 790 #if defined(OS_POSIX) && !defined(OS_NACL)
792 // On POSIX, we check if the handle is valid by seeing if the browser process 791 // On POSIX, we check if the handle is valid by seeing if the browser process
793 // sent over the switch (we don't care about the value). Invalid handles 792 // sent over the switch (we don't care about the value). Invalid handles
794 // occur in some browser tests which don't initialize the allocator. 793 // occur in some browser tests which don't initialize the allocator.
795 if (cmd_line.HasSwitch(field_trial_handle_switch)) { 794 if (cmd_line.HasSwitch(field_trial_handle_switch)) {
796 bool result = CreateTrialsFromDescriptor(fd_key); 795 std::string switch_value =
796 cmd_line.GetSwitchValueASCII(field_trial_handle_switch);
797 bool result = CreateTrialsFromDescriptor(fd_key, switch_value);
797 DCHECK(result); 798 DCHECK(result);
798 } 799 }
799 #endif 800 #endif
800 801
801 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) { 802 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) {
802 bool result = FieldTrialList::CreateTrialsFromString( 803 bool result = FieldTrialList::CreateTrialsFromString(
803 cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials), 804 cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials),
804 std::set<std::string>()); 805 std::set<std::string>());
805 DCHECK(result); 806 DCHECK(result);
806 } 807 }
(...skipping 18 matching lines...) Expand all
825 } 826 }
826 827
827 #if defined(OS_WIN) 828 #if defined(OS_WIN)
828 // static 829 // static
829 void FieldTrialList::AppendFieldTrialHandleIfNeeded( 830 void FieldTrialList::AppendFieldTrialHandleIfNeeded(
830 HandlesToInheritVector* handles) { 831 HandlesToInheritVector* handles) {
831 if (!global_) 832 if (!global_)
832 return; 833 return;
833 if (kUseSharedMemoryForFieldTrials) { 834 if (kUseSharedMemoryForFieldTrials) {
834 InstantiateFieldTrialAllocatorIfNeeded(); 835 InstantiateFieldTrialAllocatorIfNeeded();
835 if (global_->readonly_allocator_handle_) 836 if (global_->readonly_allocator_handle_.IsValid())
836 handles->push_back(global_->readonly_allocator_handle_); 837 handles->push_back(global_->readonly_allocator_handle_.GetHandle());
837 } 838 }
838 } 839 }
839 #endif 840 #endif
840 841
841 #if defined(OS_POSIX) && !defined(OS_NACL) 842 #if defined(OS_POSIX) && !defined(OS_NACL)
842 // static 843 // static
843 int FieldTrialList::GetFieldTrialHandle() { 844 SharedMemoryHandle FieldTrialList::GetFieldTrialHandle() {
844 if (global_ && kUseSharedMemoryForFieldTrials) { 845 if (global_ && kUseSharedMemoryForFieldTrials) {
845 InstantiateFieldTrialAllocatorIfNeeded(); 846 InstantiateFieldTrialAllocatorIfNeeded();
846 // We check for an invalid handle where this gets called. 847 // We check for an invalid handle where this gets called.
847 return global_->readonly_allocator_handle_; 848 return global_->readonly_allocator_handle_;
848 } 849 }
849 return kInvalidPlatformFile; 850 return SharedMemoryHandle();
850 } 851 }
851 #endif 852 #endif
852 853
853 // static 854 // static
854 void FieldTrialList::CopyFieldTrialStateToFlags( 855 void FieldTrialList::CopyFieldTrialStateToFlags(
855 const char* field_trial_handle_switch, 856 const char* field_trial_handle_switch,
856 const char* enable_features_switch, 857 const char* enable_features_switch,
857 const char* disable_features_switch, 858 const char* disable_features_switch,
858 CommandLine* cmd_line) { 859 CommandLine* cmd_line) {
859 // TODO(lawrencewu): Ideally, having the global would be guaranteed. However, 860 // TODO(lawrencewu): Ideally, having the global would be guaranteed. However,
860 // content browser tests currently don't create a FieldTrialList because they 861 // content browser tests currently don't create a FieldTrialList because they
861 // don't run ChromeBrowserMainParts code where it's done for Chrome. 862 // don't run ChromeBrowserMainParts code where it's done for Chrome.
862 // Some tests depend on the enable and disable features flag switch, though, 863 // Some tests depend on the enable and disable features flag switch, though,
863 // so we can still add those even though AllStatesToString() will be a no-op. 864 // so we can still add those even though AllStatesToString() will be a no-op.
864 if (!global_) { 865 if (!global_) {
865 AddFeatureAndFieldTrialFlags(enable_features_switch, 866 AddFeatureAndFieldTrialFlags(enable_features_switch,
866 disable_features_switch, cmd_line); 867 disable_features_switch, cmd_line);
867 return; 868 return;
868 } 869 }
869 870
870 // Use shared memory to pass the state if the feature is enabled, otherwise 871 // Use shared memory to pass the state if the feature is enabled, otherwise
871 // fallback to passing it via the command line as a string. 872 // fallback to passing it via the command line as a string.
872 if (kUseSharedMemoryForFieldTrials) { 873 if (kUseSharedMemoryForFieldTrials) {
873 InstantiateFieldTrialAllocatorIfNeeded(); 874 InstantiateFieldTrialAllocatorIfNeeded();
874 // If the readonly handle didn't get duplicated properly, then fallback to 875 // If the readonly handle didn't get duplicated properly, then fallback to
875 // original behavior. 876 // original behavior.
876 if (global_->readonly_allocator_handle_ == kInvalidPlatformFile) { 877 if (!global_->readonly_allocator_handle_.IsValid()) {
877 AddFeatureAndFieldTrialFlags(enable_features_switch, 878 AddFeatureAndFieldTrialFlags(enable_features_switch,
878 disable_features_switch, cmd_line); 879 disable_features_switch, cmd_line);
879 return; 880 return;
880 } 881 }
881 882
882 global_->field_trial_allocator_->UpdateTrackingHistograms(); 883 global_->field_trial_allocator_->UpdateTrackingHistograms();
883 884 std::string switch_value = SerializeSharedMemoryHandleMetadata(
884 #if defined(OS_WIN) 885 global_->readonly_allocator_handle_);
885 // We need to pass a named anonymous handle to shared memory over the 886 cmd_line->AppendSwitchASCII(field_trial_handle_switch, switch_value);
886 // command line on Windows, since the child doesn't know which of the
887 // handles it inherited it should open.
888 // PlatformFile is typedef'd to HANDLE which is typedef'd to void *. We
889 // basically cast the handle into an int (uintptr_t, to be exact), stringify
890 // the int, and pass it as a command-line flag. The child process will do
891 // the reverse conversions to retrieve the handle. See
892 // http://stackoverflow.com/a/153077
893 auto uintptr_handle =
894 reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_);
895 std::string field_trial_handle = std::to_string(uintptr_handle);
896 cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle);
897 #elif defined(OS_POSIX)
898 // On POSIX, we dup the fd into a fixed fd kFieldTrialDescriptor, so we
899 // don't have to pass over the handle (it's not even the right handle
900 // anyways). But some browser tests don't create the allocator, so we need
901 // to be able to distinguish valid and invalid handles. We do that by just
902 // checking that the flag is set with a dummy value.
903 cmd_line->AppendSwitchASCII(field_trial_handle_switch, "1");
904 #else
905 #error Unsupported OS
906 #endif
907 return; 887 return;
908 } 888 }
909 889
910 AddFeatureAndFieldTrialFlags(enable_features_switch, disable_features_switch, 890 AddFeatureAndFieldTrialFlags(enable_features_switch, disable_features_switch,
911 cmd_line); 891 cmd_line);
912 } 892 }
913 893
914 // static 894 // static
915 FieldTrial* FieldTrialList::CreateFieldTrial( 895 FieldTrial* FieldTrialList::CreateFieldTrial(
916 const std::string& name, 896 const std::string& name,
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 std::vector<const FieldTrial::FieldTrialEntry*> entries; 1105 std::vector<const FieldTrial::FieldTrialEntry*> entries;
1126 FieldTrialAllocator::Iterator iter(&allocator); 1106 FieldTrialAllocator::Iterator iter(&allocator);
1127 const FieldTrial::FieldTrialEntry* entry; 1107 const FieldTrial::FieldTrialEntry* entry;
1128 while ((entry = iter.GetNextOfObject<FieldTrial::FieldTrialEntry>()) != 1108 while ((entry = iter.GetNextOfObject<FieldTrial::FieldTrialEntry>()) !=
1129 nullptr) { 1109 nullptr) {
1130 entries.push_back(entry); 1110 entries.push_back(entry);
1131 } 1111 }
1132 return entries; 1112 return entries;
1133 } 1113 }
1134 1114
1115 // static
1116 std::string FieldTrialList::SerializeSharedMemoryHandleMetadata(
1117 const SharedMemoryHandle& shm) {
1118 std::stringstream ss;
1119 #if defined(OS_WIN)
1120 // Tell the child process the name of the inherited HANDLE.
1121 uintptr_t uintptr_handle = reinterpret_cast<uintptr_t>(shm.GetHandle());
1122 ss << uintptr_handle << ",";
1123 #elif !defined(OS_POSIX)
1124 #error Unsupported OS
1125 #endif
1126
1127 base::UnguessableToken guid = shm.GetGUID();
1128 ss << guid.GetHighForSerialization() << "," << guid.GetLowForSerialization();
1129 return ss.str();
1130 }
1131
1135 #if defined(OS_WIN) 1132 #if defined(OS_WIN)
1136 // static 1133 // static
1137 bool FieldTrialList::CreateTrialsFromHandleSwitch( 1134 SharedMemoryHandle FieldTrialList::DeserializeSharedMemoryHandleMetadata(
1138 const std::string& handle_switch) { 1135 const std::string& switch_value) {
1139 int field_trial_handle = std::stoi(handle_switch); 1136 std::vector<base::StringPiece> tokens = base::SplitStringPiece(
1137 switch_value, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
1138
1139 if (tokens.size() != 3)
1140 return SharedMemoryHandle();
1141
1142 int field_trial_handle = 0;
1143 if (!base::StringToInt(tokens[0], &field_trial_handle))
1144 return SharedMemoryHandle();
1140 HANDLE handle = reinterpret_cast<HANDLE>(field_trial_handle); 1145 HANDLE handle = reinterpret_cast<HANDLE>(field_trial_handle);
1141 // TODO(erikchen): Plumb a GUID for this SharedMemoryHandle. 1146
1142 // https://crbug.com/713763. 1147 base::UnguessableToken guid;
1143 SharedMemoryHandle shm_handle(handle, base::UnguessableToken::Create()); 1148 if (!DeserializeGUIDFromStringPieces(tokens[1], tokens[2], &guid))
1144 return FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle); 1149 return SharedMemoryHandle();
1150
1151 return SharedMemoryHandle(handle, guid);
1145 } 1152 }
1146 #endif 1153 #endif // defined(OS_WIN)
1147 1154
1148 #if defined(OS_POSIX) && !defined(OS_NACL) 1155 #if defined(OS_POSIX) && !defined(OS_NACL)
1149 // static 1156 // static
1150 bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) { 1157 SharedMemoryHandle FieldTrialList::DeserializeSharedMemoryHandleMetadata(
1158 int fd,
1159 const std::string& switch_value) {
1160 std::vector<base::StringPiece> tokens = base::SplitStringPiece(
1161 switch_value, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
1162
1163 if (tokens.size() != 2)
1164 return SharedMemoryHandle();
1165
1166 base::UnguessableToken guid;
1167 if (!DeserializeGUIDFromStringPieces(tokens[0], tokens[1], &guid))
1168 return SharedMemoryHandle();
1169
1170 return SharedMemoryHandle(FileDescriptor(fd, true), guid);
1171 }
1172 #endif // defined(OS_POSIX) && !defined(OS_NACL)
1173
1174 #if defined(OS_WIN)
1175 // static
1176 bool FieldTrialList::CreateTrialsFromSwitchValue(
1177 const std::string& switch_value) {
1178 SharedMemoryHandle shm = DeserializeSharedMemoryHandleMetadata(switch_value);
1179 if (!shm.IsValid())
1180 return false;
1181 return FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm);
1182 }
1183 #endif // defined(OS_WIN)
1184
1185 #if defined(OS_POSIX) && !defined(OS_NACL)
1186 // static
1187 bool FieldTrialList::CreateTrialsFromDescriptor(
1188 int fd_key,
1189 const std::string& switch_value) {
1151 if (!kUseSharedMemoryForFieldTrials) 1190 if (!kUseSharedMemoryForFieldTrials)
1152 return false; 1191 return false;
1153 1192
1154 if (fd_key == -1) 1193 if (fd_key == -1)
1155 return false; 1194 return false;
1156 1195
1157 int fd = GlobalDescriptors::GetInstance()->MaybeGet(fd_key); 1196 int fd = GlobalDescriptors::GetInstance()->MaybeGet(fd_key);
1158 if (fd == -1) 1197 if (fd == -1)
1159 return false; 1198 return false;
1160 1199
1161 // TODO(erikchen): Plumb a GUID for this SharedMemoryHandle. 1200 SharedMemoryHandle shm =
1162 // https://crbug.com/713763. 1201 DeserializeSharedMemoryHandleMetadata(fd, switch_value);
1163 SharedMemoryHandle shm_handle(FileDescriptor(fd, true), 1202 if (!shm.IsValid())
1164 base::UnguessableToken::Create()); 1203 return false;
1165 1204
1166 bool result = FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle); 1205 bool result = FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm);
1167 DCHECK(result); 1206 DCHECK(result);
1168 return true; 1207 return true;
1169 } 1208 }
1170 #endif 1209 #endif // defined(OS_POSIX) && !defined(OS_NACL)
1171 1210
1172 // static 1211 // static
1173 bool FieldTrialList::CreateTrialsFromSharedMemoryHandle( 1212 bool FieldTrialList::CreateTrialsFromSharedMemoryHandle(
1174 SharedMemoryHandle shm_handle) { 1213 SharedMemoryHandle shm_handle) {
1175 // shm gets deleted when it gets out of scope, but that's OK because we need 1214 // shm gets deleted when it gets out of scope, but that's OK because we need
1176 // it only for the duration of this method. 1215 // it only for the duration of this method.
1177 std::unique_ptr<SharedMemory> shm(new SharedMemory(shm_handle, true)); 1216 std::unique_ptr<SharedMemory> shm(new SharedMemory(shm_handle, true));
1178 if (!shm.get()->Map(kFieldTrialAllocationSize)) 1217 if (!shm.get()->Map(kFieldTrialAllocationSize))
1179 OnOutOfMemory(kFieldTrialAllocationSize); 1218 OnOutOfMemory(kFieldTrialAllocationSize);
1180 1219
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 } 1286 }
1248 1287
1249 // Add all existing features. 1288 // Add all existing features.
1250 FeatureList::GetInstance()->AddFeaturesToAllocator( 1289 FeatureList::GetInstance()->AddFeaturesToAllocator(
1251 global_->field_trial_allocator_.get()); 1290 global_->field_trial_allocator_.get());
1252 1291
1253 #if !defined(OS_NACL) 1292 #if !defined(OS_NACL)
1254 // Set |readonly_allocator_handle_| so we can pass it to be inherited and 1293 // Set |readonly_allocator_handle_| so we can pass it to be inherited and
1255 // via the command line. 1294 // via the command line.
1256 global_->readonly_allocator_handle_ = 1295 global_->readonly_allocator_handle_ =
1257 CreateReadOnlyHandle(global_->field_trial_allocator_.get()); 1296 global_->field_trial_allocator_->shared_memory()->GetReadOnlyHandle();
1258 #endif 1297 #endif
1259 } 1298 }
1260 1299
1261 // static 1300 // static
1262 void FieldTrialList::AddToAllocatorWhileLocked( 1301 void FieldTrialList::AddToAllocatorWhileLocked(
1263 PersistentMemoryAllocator* allocator, 1302 PersistentMemoryAllocator* allocator,
1264 FieldTrial* field_trial) { 1303 FieldTrial* field_trial) {
1265 // Don't do anything if the allocator hasn't been instantiated yet. 1304 // Don't do anything if the allocator hasn't been instantiated yet.
1266 if (allocator == nullptr) 1305 if (allocator == nullptr)
1267 return; 1306 return;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 return; 1398 return;
1360 } 1399 }
1361 AutoLock auto_lock(global_->lock_); 1400 AutoLock auto_lock(global_->lock_);
1362 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); 1401 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
1363 trial->AddRef(); 1402 trial->AddRef();
1364 trial->SetTrialRegistered(); 1403 trial->SetTrialRegistered();
1365 global_->registered_[trial->trial_name()] = trial; 1404 global_->registered_[trial->trial_name()] = trial;
1366 } 1405 }
1367 1406
1368 } // namespace base 1407 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/field_trial.h ('k') | base/metrics/field_trial_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698