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 #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 Loading... | |
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 |
238 } // namespace | 220 } // namespace |
239 | 221 |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
768 // processes are properly reported in crash reports. | 750 // processes are properly reported in crash reports. |
769 trial->group(); | 751 trial->group(); |
770 } | 752 } |
771 } | 753 } |
772 return true; | 754 return true; |
773 } | 755 } |
774 | 756 |
775 // static | 757 // static |
776 void FieldTrialList::CreateTrialsFromCommandLine( | 758 void FieldTrialList::CreateTrialsFromCommandLine( |
777 const CommandLine& cmd_line, | 759 const CommandLine& cmd_line, |
778 const char* field_trial_handle_switch, | 760 const char* field_trial_switch_value, |
Alexei Svitkine (slow)
2017/05/05 22:37:50
Nit: You still have a sed error here :P
erikchen
2017/05/08 23:37:49
Done.
| |
779 int fd_key) { | 761 int fd_key) { |
780 global_->create_trials_from_command_line_called_ = true; | 762 global_->create_trials_from_command_line_called_ = true; |
781 | 763 |
782 #if defined(OS_WIN) | 764 #if defined(OS_WIN) |
783 if (cmd_line.HasSwitch(field_trial_handle_switch)) { | 765 if (cmd_line.HasSwitch(field_trial_switch_value)) { |
784 std::string handle_switch = | 766 std::string switch_value = |
785 cmd_line.GetSwitchValueASCII(field_trial_handle_switch); | 767 cmd_line.GetSwitchValueASCII(field_trial_switch_value); |
786 bool result = CreateTrialsFromHandleSwitch(handle_switch); | 768 bool result = CreateTrialsFromSwitchValue(switch_value); |
787 DCHECK(result); | 769 DCHECK(result); |
788 } | 770 } |
789 #endif | 771 #endif |
790 | 772 |
791 #if defined(OS_POSIX) && !defined(OS_NACL) | 773 #if defined(OS_POSIX) && !defined(OS_NACL) |
792 // On POSIX, we check if the handle is valid by seeing if the browser process | 774 // 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 | 775 // 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. | 776 // occur in some browser tests which don't initialize the allocator. |
795 if (cmd_line.HasSwitch(field_trial_handle_switch)) { | 777 if (cmd_line.HasSwitch(field_trial_switch_value)) { |
796 bool result = CreateTrialsFromDescriptor(fd_key); | 778 std::string switch_value = |
779 cmd_line.GetSwitchValueASCII(field_trial_switch_value); | |
780 bool result = CreateTrialsFromDescriptor(fd_key, switch_value); | |
797 DCHECK(result); | 781 DCHECK(result); |
798 } | 782 } |
799 #endif | 783 #endif |
800 | 784 |
801 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) { | 785 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) { |
802 bool result = FieldTrialList::CreateTrialsFromString( | 786 bool result = FieldTrialList::CreateTrialsFromString( |
803 cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials), | 787 cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials), |
804 std::set<std::string>()); | 788 std::set<std::string>()); |
805 DCHECK(result); | 789 DCHECK(result); |
806 } | 790 } |
(...skipping 18 matching lines...) Expand all Loading... | |
825 } | 809 } |
826 | 810 |
827 #if defined(OS_WIN) | 811 #if defined(OS_WIN) |
828 // static | 812 // static |
829 void FieldTrialList::AppendFieldTrialHandleIfNeeded( | 813 void FieldTrialList::AppendFieldTrialHandleIfNeeded( |
830 HandlesToInheritVector* handles) { | 814 HandlesToInheritVector* handles) { |
831 if (!global_) | 815 if (!global_) |
832 return; | 816 return; |
833 if (kUseSharedMemoryForFieldTrials) { | 817 if (kUseSharedMemoryForFieldTrials) { |
834 InstantiateFieldTrialAllocatorIfNeeded(); | 818 InstantiateFieldTrialAllocatorIfNeeded(); |
835 if (global_->readonly_allocator_handle_) | 819 if (global_->readonly_allocator_handle_.IsValid()) |
836 handles->push_back(global_->readonly_allocator_handle_); | 820 handles->push_back(global_->readonly_allocator_handle_.GetHandle()); |
837 } | 821 } |
838 } | 822 } |
839 #endif | 823 #endif |
840 | 824 |
841 #if defined(OS_POSIX) && !defined(OS_NACL) | 825 #if defined(OS_POSIX) && !defined(OS_NACL) |
842 // static | 826 // static |
843 int FieldTrialList::GetFieldTrialHandle() { | 827 SharedMemoryHandle FieldTrialList::GetFieldTrialHandle() { |
844 if (global_ && kUseSharedMemoryForFieldTrials) { | 828 if (global_ && kUseSharedMemoryForFieldTrials) { |
845 InstantiateFieldTrialAllocatorIfNeeded(); | 829 InstantiateFieldTrialAllocatorIfNeeded(); |
846 // We check for an invalid handle where this gets called. | 830 // We check for an invalid handle where this gets called. |
847 return global_->readonly_allocator_handle_; | 831 return global_->readonly_allocator_handle_; |
848 } | 832 } |
849 return kInvalidPlatformFile; | 833 return SharedMemoryHandle(); |
850 } | 834 } |
851 #endif | 835 #endif |
852 | 836 |
853 // static | 837 // static |
854 void FieldTrialList::CopyFieldTrialStateToFlags( | 838 void FieldTrialList::CopyFieldTrialStateToFlags( |
855 const char* field_trial_handle_switch, | 839 const char* field_trial_handle_switch, |
856 const char* enable_features_switch, | 840 const char* enable_features_switch, |
857 const char* disable_features_switch, | 841 const char* disable_features_switch, |
858 CommandLine* cmd_line) { | 842 CommandLine* cmd_line) { |
859 // TODO(lawrencewu): Ideally, having the global would be guaranteed. However, | 843 // TODO(lawrencewu): Ideally, having the global would be guaranteed. However, |
860 // content browser tests currently don't create a FieldTrialList because they | 844 // content browser tests currently don't create a FieldTrialList because they |
861 // don't run ChromeBrowserMainParts code where it's done for Chrome. | 845 // don't run ChromeBrowserMainParts code where it's done for Chrome. |
862 // Some tests depend on the enable and disable features flag switch, though, | 846 // 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. | 847 // so we can still add those even though AllStatesToString() will be a no-op. |
864 if (!global_) { | 848 if (!global_) { |
865 AddFeatureAndFieldTrialFlags(enable_features_switch, | 849 AddFeatureAndFieldTrialFlags(enable_features_switch, |
866 disable_features_switch, cmd_line); | 850 disable_features_switch, cmd_line); |
867 return; | 851 return; |
868 } | 852 } |
869 | 853 |
870 // Use shared memory to pass the state if the feature is enabled, otherwise | 854 // 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. | 855 // fallback to passing it via the command line as a string. |
872 if (kUseSharedMemoryForFieldTrials) { | 856 if (kUseSharedMemoryForFieldTrials) { |
873 InstantiateFieldTrialAllocatorIfNeeded(); | 857 InstantiateFieldTrialAllocatorIfNeeded(); |
874 // If the readonly handle didn't get duplicated properly, then fallback to | 858 // If the readonly handle didn't get duplicated properly, then fallback to |
875 // original behavior. | 859 // original behavior. |
876 if (global_->readonly_allocator_handle_ == kInvalidPlatformFile) { | 860 if (!global_->readonly_allocator_handle_.IsValid()) { |
877 AddFeatureAndFieldTrialFlags(enable_features_switch, | 861 AddFeatureAndFieldTrialFlags(enable_features_switch, |
878 disable_features_switch, cmd_line); | 862 disable_features_switch, cmd_line); |
879 return; | 863 return; |
880 } | 864 } |
881 | 865 |
882 global_->field_trial_allocator_->UpdateTrackingHistograms(); | 866 global_->field_trial_allocator_->UpdateTrackingHistograms(); |
883 | 867 std::string switch_value = SerializeSharedMemoryHandleMetadata( |
884 #if defined(OS_WIN) | 868 global_->readonly_allocator_handle_); |
885 // We need to pass a named anonymous handle to shared memory over the | 869 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; | 870 return; |
908 } | 871 } |
909 | 872 |
910 AddFeatureAndFieldTrialFlags(enable_features_switch, disable_features_switch, | 873 AddFeatureAndFieldTrialFlags(enable_features_switch, disable_features_switch, |
911 cmd_line); | 874 cmd_line); |
912 } | 875 } |
913 | 876 |
914 // static | 877 // static |
915 FieldTrial* FieldTrialList::CreateFieldTrial( | 878 FieldTrial* FieldTrialList::CreateFieldTrial( |
916 const std::string& name, | 879 const std::string& name, |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1125 std::vector<const FieldTrial::FieldTrialEntry*> entries; | 1088 std::vector<const FieldTrial::FieldTrialEntry*> entries; |
1126 FieldTrialAllocator::Iterator iter(&allocator); | 1089 FieldTrialAllocator::Iterator iter(&allocator); |
1127 const FieldTrial::FieldTrialEntry* entry; | 1090 const FieldTrial::FieldTrialEntry* entry; |
1128 while ((entry = iter.GetNextOfObject<FieldTrial::FieldTrialEntry>()) != | 1091 while ((entry = iter.GetNextOfObject<FieldTrial::FieldTrialEntry>()) != |
1129 nullptr) { | 1092 nullptr) { |
1130 entries.push_back(entry); | 1093 entries.push_back(entry); |
1131 } | 1094 } |
1132 return entries; | 1095 return entries; |
1133 } | 1096 } |
1134 | 1097 |
1098 // static | |
1099 std::string FieldTrialList::SerializeSharedMemoryHandleMetadata( | |
1100 const SharedMemoryHandle& shm) { | |
1101 std::stringstream ss; | |
1102 #if defined(OS_WIN) | |
1103 // Tell the child process the name of the inherited HANDLE. | |
1104 uintptr_t uintptr_handle = reinterpret_cast<uintptr_t>(shm.GetHandle()); | |
1105 ss << uintptr_handle << ","; | |
1106 #elif !defined(OS_POSIX) | |
1107 #error Unsupported OS | |
1108 #endif | |
1109 | |
1110 base::UnguessableToken guid = shm.GetGUID(); | |
1111 ss << guid.GetHighForSerialization() << "," << guid.GetLowForSerialization(); | |
1112 return ss.str(); | |
1113 } | |
1114 | |
1135 #if defined(OS_WIN) | 1115 #if defined(OS_WIN) |
1136 // static | 1116 // static |
1137 bool FieldTrialList::CreateTrialsFromHandleSwitch( | 1117 SharedMemoryHandle FieldTrialList::DeserializeSharedMemoryHandleMetadata( |
1138 const std::string& handle_switch) { | 1118 const std::string& switch_value) { |
1139 int field_trial_handle = std::stoi(handle_switch); | 1119 std::vector<std::string> tokens = base::SplitString( |
Alexei Svitkine (slow)
2017/05/05 22:37:50
Nit: Use StringSplitPiece() version
erikchen
2017/05/08 23:37:49
Done.
| |
1120 switch_value, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | |
1121 | |
1122 if (tokens.size() != 3) | |
1123 return SharedMemoryHandle(); | |
1124 | |
1125 int field_trial_handle = 0; | |
1126 if (!base::StringToInt(tokens[0], &field_trial_handle)) | |
1127 return SharedMemoryHandle(); | |
1140 HANDLE handle = reinterpret_cast<HANDLE>(field_trial_handle); | 1128 HANDLE handle = reinterpret_cast<HANDLE>(field_trial_handle); |
1141 // TODO(erikchen): Plumb a GUID for this SharedMemoryHandle. | 1129 |
1142 // https://crbug.com/713763. | 1130 uint64_t high = 0; |
1143 SharedMemoryHandle shm_handle(handle, base::UnguessableToken::Create()); | 1131 if (!base::StringToUint64(tokens[1], &high)) |
1144 return FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle); | 1132 return SharedMemoryHandle(); |
1133 uint64_t low = 0; | |
1134 if (!base::StringToUint64(tokens[2], &low)) | |
1135 return SharedMemoryHandle(); | |
1136 | |
1137 base::UnguessableToken guid = base::UnguessableToken::Deserialize(high, low); | |
1138 return SharedMemoryHandle(handle, guid); | |
1139 } | |
1140 | |
1141 // static | |
1142 bool FieldTrialList::CreateTrialsFromSwitchValue( | |
1143 const std::string& switch_value) { | |
Alexei Svitkine (slow)
2017/05/05 22:37:50
Please match the same order in .cc as in .h file -
erikchen
2017/05/08 23:37:49
Done.
| |
1144 SharedMemoryHandle shm = DeserializeSharedMemoryHandleMetadata(switch_value); | |
1145 if (!shm.IsValid()) | |
1146 return false; | |
1147 return FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm); | |
1145 } | 1148 } |
1146 #endif | 1149 #endif |
1147 | 1150 |
1148 #if defined(OS_POSIX) && !defined(OS_NACL) | 1151 #if defined(OS_POSIX) && !defined(OS_NACL) |
1149 // static | 1152 // static |
1150 bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) { | 1153 SharedMemoryHandle FieldTrialList::DeserializeSharedMemoryHandleMetadata( |
1154 int fd, | |
1155 const std::string& switch_value) { | |
1156 std::vector<std::string> tokens = base::SplitString( | |
1157 switch_value, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | |
1158 | |
1159 if (tokens.size() != 2) | |
1160 return SharedMemoryHandle(); | |
1161 uint64_t high = 0; | |
1162 if (!base::StringToUint64(tokens[0], &high)) | |
1163 return SharedMemoryHandle(); | |
1164 uint64_t low = 0; | |
1165 if (!base::StringToUint64(tokens[1], &low)) | |
1166 return SharedMemoryHandle(); | |
Alexei Svitkine (slow)
2017/05/05 22:37:50
Nit: I find the following a bit cleaner:
uint64_t
erikchen
2017/05/08 23:37:49
Done.
| |
1167 | |
1168 base::UnguessableToken guid = base::UnguessableToken::Deserialize(high, low); | |
Alexei Svitkine (slow)
2017/05/05 22:37:51
Suggest making a helper anon function to share thi
erikchen
2017/05/08 23:37:49
Done.
| |
1169 return SharedMemoryHandle(FileDescriptor(fd, true), guid); | |
1170 } | |
1171 | |
1172 // static | |
1173 bool FieldTrialList::CreateTrialsFromDescriptor( | |
1174 int fd_key, | |
1175 const std::string& switch_value) { | |
1151 if (!kUseSharedMemoryForFieldTrials) | 1176 if (!kUseSharedMemoryForFieldTrials) |
1152 return false; | 1177 return false; |
1153 | 1178 |
1154 if (fd_key == -1) | 1179 if (fd_key == -1) |
1155 return false; | 1180 return false; |
1156 | 1181 |
1157 int fd = GlobalDescriptors::GetInstance()->MaybeGet(fd_key); | 1182 int fd = GlobalDescriptors::GetInstance()->MaybeGet(fd_key); |
1158 if (fd == -1) | 1183 if (fd == -1) |
1159 return false; | 1184 return false; |
1160 | 1185 |
1161 // TODO(erikchen): Plumb a GUID for this SharedMemoryHandle. | 1186 SharedMemoryHandle shm = |
1162 // https://crbug.com/713763. | 1187 DeserializeSharedMemoryHandleMetadata(fd, switch_value); |
1163 SharedMemoryHandle shm_handle(FileDescriptor(fd, true), | 1188 if (!shm.IsValid()) |
1164 base::UnguessableToken::Create()); | 1189 return false; |
1165 | 1190 |
1166 bool result = FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle); | 1191 bool result = FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm); |
1167 DCHECK(result); | 1192 DCHECK(result); |
1168 return true; | 1193 return true; |
1169 } | 1194 } |
1170 #endif | 1195 #endif |
1171 | 1196 |
1172 // static | 1197 // static |
1173 bool FieldTrialList::CreateTrialsFromSharedMemoryHandle( | 1198 bool FieldTrialList::CreateTrialsFromSharedMemoryHandle( |
1174 SharedMemoryHandle shm_handle) { | 1199 SharedMemoryHandle shm_handle) { |
1175 // shm gets deleted when it gets out of scope, but that's OK because we need | 1200 // 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. | 1201 // it only for the duration of this method. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1247 } | 1272 } |
1248 | 1273 |
1249 // Add all existing features. | 1274 // Add all existing features. |
1250 FeatureList::GetInstance()->AddFeaturesToAllocator( | 1275 FeatureList::GetInstance()->AddFeaturesToAllocator( |
1251 global_->field_trial_allocator_.get()); | 1276 global_->field_trial_allocator_.get()); |
1252 | 1277 |
1253 #if !defined(OS_NACL) | 1278 #if !defined(OS_NACL) |
1254 // Set |readonly_allocator_handle_| so we can pass it to be inherited and | 1279 // Set |readonly_allocator_handle_| so we can pass it to be inherited and |
1255 // via the command line. | 1280 // via the command line. |
1256 global_->readonly_allocator_handle_ = | 1281 global_->readonly_allocator_handle_ = |
1257 CreateReadOnlyHandle(global_->field_trial_allocator_.get()); | 1282 global_->field_trial_allocator_->shared_memory()->GetReadOnlyHandle(); |
1258 #endif | 1283 #endif |
1259 } | 1284 } |
1260 | 1285 |
1261 // static | 1286 // static |
1262 void FieldTrialList::AddToAllocatorWhileLocked( | 1287 void FieldTrialList::AddToAllocatorWhileLocked( |
1263 PersistentMemoryAllocator* allocator, | 1288 PersistentMemoryAllocator* allocator, |
1264 FieldTrial* field_trial) { | 1289 FieldTrial* field_trial) { |
1265 // Don't do anything if the allocator hasn't been instantiated yet. | 1290 // Don't do anything if the allocator hasn't been instantiated yet. |
1266 if (allocator == nullptr) | 1291 if (allocator == nullptr) |
1267 return; | 1292 return; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1359 return; | 1384 return; |
1360 } | 1385 } |
1361 AutoLock auto_lock(global_->lock_); | 1386 AutoLock auto_lock(global_->lock_); |
1362 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); | 1387 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); |
1363 trial->AddRef(); | 1388 trial->AddRef(); |
1364 trial->SetTrialRegistered(); | 1389 trial->SetTrialRegistered(); |
1365 global_->registered_[trial->trial_name()] = trial; | 1390 global_->registered_[trial->trial_name()] = trial; |
1366 } | 1391 } |
1367 | 1392 |
1368 } // namespace base | 1393 } // namespace base |
OLD | NEW |