diff options
author | Aditya Mandaleeka <adityam@microsoft.com> | 2016-03-11 18:39:27 -0800 |
---|---|---|
committer | Aditya Mandaleeka <adityam@microsoft.com> | 2016-03-25 17:54:53 -0700 |
commit | 1aa1b8ba64365f8b93a505d4f6165c6eaad84a7a (patch) | |
tree | 8959cf6022f00a12084aad1c4139d3ba3a5c9501 /src/utilcode | |
parent | 6cbd27ede090e1731b96d4d2b18813adb67e1487 (diff) | |
download | coreclr-1aa1b8ba64365f8b93a505d4f6165c6eaad84a7a.tar.gz coreclr-1aa1b8ba64365f8b93a505d4f6165c6eaad84a7a.tar.bz2 coreclr-1aa1b8ba64365f8b93a505d4f6165c6eaad84a7a.zip |
Add new configuration mechanism for CoreCLR.
Diffstat (limited to 'src/utilcode')
-rw-r--r-- | src/utilcode/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/utilcode/UtilCode.vcproj | 3 | ||||
-rw-r--r-- | src/utilcode/UtilCode.vcxproj | 1 | ||||
-rw-r--r-- | src/utilcode/clrconfig.cpp | 128 | ||||
-rw-r--r-- | src/utilcode/configuration.cpp | 125 | ||||
-rw-r--r-- | src/utilcode/utilcode.settings.targets | 1 |
6 files changed, 227 insertions, 32 deletions
diff --git a/src/utilcode/CMakeLists.txt b/src/utilcode/CMakeLists.txt index 001205a62b..9d35a7e641 100644 --- a/src/utilcode/CMakeLists.txt +++ b/src/utilcode/CMakeLists.txt @@ -16,6 +16,7 @@ set(UTILCODE_COMMON_SOURCES makepath.cpp splitpath.cpp clrconfig.cpp + configuration.cpp collections.cpp posterror.cpp fstream.cpp diff --git a/src/utilcode/UtilCode.vcproj b/src/utilcode/UtilCode.vcproj index c12516464a..286456616e 100644 --- a/src/utilcode/UtilCode.vcproj +++ b/src/utilcode/UtilCode.vcproj @@ -375,6 +375,9 @@ <File RelativePath=".\CLRConfig.cpp" > + <File + RelativePath=".\configuration.cpp" + > </File> <File RelativePath=".\clrhost.cpp" diff --git a/src/utilcode/UtilCode.vcxproj b/src/utilcode/UtilCode.vcxproj index 54afef7da4..d3f6add8bb 100644 --- a/src/utilcode/UtilCode.vcxproj +++ b/src/utilcode/UtilCode.vcxproj @@ -382,6 +382,7 @@ <ClCompile Include="check.cpp" /> <ClCompile Include="circularlog.cpp" /> <ClCompile Include="CLRConfig.cpp" /> + <ClCompile Include="configuration.cpp" /> <ClCompile Include="clrhost.cpp" /> <ClCompile Include="COMEx.cpp" /> <ClCompile Include="corimage.cpp" /> diff --git a/src/utilcode/clrconfig.cpp b/src/utilcode/clrconfig.cpp index c8a82060e9..163974999d 100644 --- a/src/utilcode/clrconfig.cpp +++ b/src/utilcode/clrconfig.cpp @@ -297,16 +297,25 @@ BOOL CLRConfig::IsConfigEnabled(const ConfigDWORDInfo & info) return FALSE; } - - // // Look up a DWORD config value. // // Arguments: -// * info - see file:../inc/CLRConfig.h for details -// +// * info - see file:../inc/CLRConfig.h for details. +// +// * useDefaultIfNotSet - if true, fall back to the default value if the value is not set. +// +// * acceptExplicitDefaultFromRegutil - if false, only accept a value returned by REGUTIL if it is +// different from the default value. This parameter is useful as a way to preserve existing +// behavior. +// +// * result - the result. +// +// Return value: +// * true for success, false otherwise. +// // static -DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info) +DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info, bool acceptExplicitDefaultFromRegutil, /* [Out] */ bool *isDefault) { CONTRACTL { @@ -317,7 +326,7 @@ DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info) } CONTRACTL_END; - DWORD result = info.defaultValue; + _ASSERTE (isDefault != nullptr); #ifdef FEATURE_WIN_DB_APPCOMPAT // Windows Shim DB should be the first place to look as it applies microsoft enforced policy @@ -325,7 +334,6 @@ DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info) if(CheckLookupOption(info, IgnoreWindowsQuirkDB) == FALSE && s_IsQuirkEnabledCallback != NULL )// Check that IsQuirkEnabledCallback function has been registered. { - BOOL isEnabledInDB = FALSE; CPT_QUIRK_DATA quirkData; if(SUCCEEDED(getQuirkEnabledAndValueFromWinDB(info.name, &isEnabledInDB, &quirkData))) @@ -334,19 +342,21 @@ DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info) { WCHAR *end; errno = 0; - result = wcstoul(quirkData.CommandLine, &end, 0); - + DWORD resultMaybe = wcstoul(quirkData.CommandLine, &end, 0); + // errno is ERANGE if the number is out of range, and end is set to pvalue if // no valid conversion exists. if (errno != ERANGE && end != quirkData.CommandLine) { - return result; + *isDefault = false; + return resultMaybe; } else { // If an invalid value is defined we treat it as the default value. // i.e. we don't look further. - return info.defaultValue; + *isDefault = true; + return info.defaultValue; } } } @@ -362,46 +372,64 @@ DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info) // // If we aren't favoring config files, we check REGUTIL here. // - if(CheckLookupOption(info, FavorConfigFile) == FALSE) + if (CheckLookupOption(info, FavorConfigFile) == FALSE) { - REGUTIL::GetConfigDWORD_DontUse_(info.name, info.defaultValue, &result, level, prependCOMPlus); - // TODO: We are ignoring explicitly defined default values to avoid change in behavior. - // TODO: Ideally, the following should check the hresult for success. - if(result != info.defaultValue) + DWORD resultMaybe; + HRESULT hr = REGUTIL::GetConfigDWORD_DontUse_(info.name, info.defaultValue, &resultMaybe, level, prependCOMPlus); + + if (!acceptExplicitDefaultFromRegutil) { - return result; + // Ignore the default value even if it's set explicitly. + if (resultMaybe != info.defaultValue) + { + *isDefault = false; + return resultMaybe; + } + } + else + { + // If we are willing to accept the default value when it's set explicitly, + // checking the HRESULT here is sufficient. E_FAIL is returned when the + // default is used. + if (SUCCEEDED(hr)) + { + *isDefault = false; + return resultMaybe; + } } } // // Check config files through EEConfig. // - if(CheckLookupOption(info, IgnoreConfigFiles) == FALSE && // Check that we aren't ignoring config files. + if (CheckLookupOption(info, IgnoreConfigFiles) == FALSE && // Check that we aren't ignoring config files. s_GetConfigValueCallback != NULL)// Check that GetConfigValueCallback function has been registered. - { + { LPCWSTR pvalue; // EEConfig lookup options. BOOL systemOnly = CheckLookupOption(info, ConfigFile_SystemOnly) ? TRUE : FALSE; BOOL applicationFirst = CheckLookupOption(info, ConfigFile_ApplicationFirst) ? TRUE : FALSE; - - if(SUCCEEDED(s_GetConfigValueCallback(info.name, &pvalue, systemOnly, applicationFirst)) && pvalue != NULL) + + if (SUCCEEDED(s_GetConfigValueCallback(info.name, &pvalue, systemOnly, applicationFirst)) && pvalue != NULL) { WCHAR * end; errno = 0; - result = wcstoul(pvalue, &end, 0); - + DWORD resultMaybe = wcstoul(pvalue, &end, 0); + // errno is ERANGE if the number is out of range, and end is set to pvalue if // no valid conversion exists. if (errno != ERANGE && end != pvalue) { - return result; + *isDefault = false; + return resultMaybe; } else { // If an invalid value is defined we treat it as the default value. // i.e. we don't look further. - return info.defaultValue; + *isDefault = true; + return info.defaultValue; } } } @@ -409,14 +437,30 @@ DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info) // // If we are favoring config files and we don't have a result from EEConfig, we check REGUTIL here. // - if(CheckLookupOption(info, FavorConfigFile) == TRUE) + if (CheckLookupOption(info, FavorConfigFile) == TRUE) { - REGUTIL::GetConfigDWORD_DontUse_(info.name, info.defaultValue, &result, level, prependCOMPlus); - // TODO: We are ignoring explicitly defined default values to avoid change in behavior. - // TODO: Ideally, the following should check the hresult for success. - if(result != info.defaultValue) + DWORD resultMaybe; + HRESULT hr = REGUTIL::GetConfigDWORD_DontUse_(info.name, info.defaultValue, &resultMaybe, level, prependCOMPlus); + + if (!acceptExplicitDefaultFromRegutil) { - return result; + // Ignore the default value even if it's set explicitly. + if (resultMaybe != info.defaultValue) + { + *isDefault = false; + return resultMaybe; + } + } + else + { + // If we are willing to accept the default value when it's set explicitly, + // checking the HRESULT here is sufficient. E_FAIL is returned when the + // default is used. + if (SUCCEEDED(hr)) + { + *isDefault = false; + return resultMaybe; + } } } @@ -431,14 +475,34 @@ DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info) { // TODO: We ignore explicitly defined default values above, but we do not want to let performance defaults override these. // TODO: Ideally, the above would use hresult for success and this check would be removed. - if (!SUCCEEDED(REGUTIL::GetConfigDWORD_DontUse_(info.name, info.defaultValue, &result, level, prependCOMPlus))) + DWORD resultMaybe; + if (!SUCCEEDED(REGUTIL::GetConfigDWORD_DontUse_(info.name, info.defaultValue, &resultMaybe, level, prependCOMPlus))) + { + *isDefault = true; return performanceDefaultValue; + } } + *isDefault = true; return info.defaultValue; } // +// Look up a DWORD config value. +// +// Arguments: +// * info - see file:../inc/CLRConfig.h for details +// +// static +DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info) +{ + // We pass false for 'acceptExplicitDefaultFromRegutil' to maintain the existing behavior of this function. + // Callers who don't need that behavior should switch to the other version of this function and pass true. + bool unused; + return GetConfigValue(info, false /* acceptExplicitDefaultFromRegutil */, &unused); +} + +// // Look up a String config value. // // Arguments: diff --git a/src/utilcode/configuration.cpp b/src/utilcode/configuration.cpp new file mode 100644 index 0000000000..817bc06e90 --- /dev/null +++ b/src/utilcode/configuration.cpp @@ -0,0 +1,125 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// +// -------------------------------------------------------------------------------------------------- +// configuration.cpp +// +// +// Access and update configuration values, falling back on legacy CLRConfig methods where necessary. +// +// -------------------------------------------------------------------------------------------------- + +#include "stdafx.h" + +#include "clrconfig.h" +#include "configuration.h" + +LPCWSTR *knobNames = nullptr; +LPCWSTR *knobValues = nullptr; +int numberOfKnobs = 0; + +void Configuration::InitializeConfigurationKnobs(int numberOfConfigs, LPCWSTR *names, LPCWSTR *values) +{ + numberOfKnobs = numberOfConfigs; + + // Neither should be null, or both should be null + _ASSERT(!((names == nullptr) ^ (values == nullptr))); + + knobNames = names; + knobValues = values; +} + +static LPCWSTR GetConfigurationValue(LPCWSTR name) +{ + _ASSERT(name != nullptr); + if (name == nullptr || knobNames == nullptr || knobValues == nullptr) + { + return nullptr; + } + + for (int i = 0; i < numberOfKnobs; ++i) + { + _ASSERT(knobNames[i] != nullptr); + if (wcscmp(name, knobNames[i]) == 0) + { + return knobValues[i]; + } + } + + return nullptr; +} + +DWORD Configuration::GetKnobDWORDValue(LPCWSTR name, const CLRConfig::ConfigDWORDInfo& dwordInfo) +{ + bool returnedDefaultValue; + DWORD legacyValue = CLRConfig::GetConfigValue(dwordInfo, true /* acceptExplicitDefaultFromRegutil */, &returnedDefaultValue); + if (!returnedDefaultValue) + { + return legacyValue; + } + + LPCWSTR knobValue = GetConfigurationValue(name); + if (knobValue != nullptr) + { + return wcstoul(knobValue, nullptr, 0); + } + + return legacyValue; +} + +DWORD Configuration::GetKnobDWORDValue(LPCWSTR name, DWORD defaultValue) +{ + LPCWSTR knobValue = GetConfigurationValue(name); + if (knobValue != nullptr) + { + return wcstoul(knobValue, nullptr, 0); + } + + return defaultValue; +} + +LPCWSTR Configuration::GetKnobStringValue(LPCWSTR name, const CLRConfig::ConfigStringInfo& stringInfo) +{ + LPCWSTR value = CLRConfig::GetConfigValue(stringInfo); + if (value == nullptr) + { + value = GetConfigurationValue(name); + } + + return value; +} + +LPCWSTR Configuration::GetKnobStringValue(LPCWSTR name) +{ + return GetConfigurationValue(name); +} + +bool Configuration::GetKnobBooleanValue(LPCWSTR name, const CLRConfig::ConfigDWORDInfo& dwordInfo) +{ + bool returnedDefaultValue; + DWORD legacyValue = CLRConfig::GetConfigValue(dwordInfo, true /* acceptExplicitDefaultFromRegutil */, &returnedDefaultValue); + if (!returnedDefaultValue) + { + return (legacyValue != 0); + } + + LPCWSTR knobValue = GetConfigurationValue(name); + if (knobValue != nullptr) + { + return (wcscmp(knobValue, W("true")) == 0); + } + + return (legacyValue != 0); +} + +bool Configuration::GetKnobBooleanValue(LPCWSTR name, bool defaultValue) +{ + LPCWSTR knobValue = GetConfigurationValue(name); + if (knobValue != nullptr) + { + return (wcscmp(knobValue, W("true")) == 0); + } + + return defaultValue; +}
\ No newline at end of file diff --git a/src/utilcode/utilcode.settings.targets b/src/utilcode/utilcode.settings.targets index 7c11fd50b4..7fbcb4d5cc 100644 --- a/src/utilcode/utilcode.settings.targets +++ b/src/utilcode/utilcode.settings.targets @@ -45,6 +45,7 @@ <CppCompile Include="$(UtilCodeSrcDir)\SplitPath.cpp" /> <CppCompile Include="$(UtilCodeSrcDir)\ClrConfig.cpp" /> + <CppCompile Include="$(UtilCodeSrcDir)\configuration.cpp" /> <CppCompile Include="$(UtilCodeSrcDir)\RegUtil.cpp" /> <CppCompile Include="$(UtilCodeSrcDir)\RegistryWrapper.cpp" /> |