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 |
| 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |