Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2015-10-01 00:47:24 +0300
committerScott Mosier <smosier@microsoft.com>2015-10-01 00:47:24 +0300
commitad0323ab91a7b1469b42ca5457ddd631b94294fe (patch)
tree88fae57e1ec3aae90288463dc07e58f7aebc1de8 /src/Native/Runtime/RhConfig.h
parent6763d16387778f126ec510c0421783952602f8f7 (diff)
Initial population of CoreRT Runtime files.
Diffstat (limited to 'src/Native/Runtime/RhConfig.h')
-rw-r--r--src/Native/Runtime/RhConfig.h130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/Native/Runtime/RhConfig.h b/src/Native/Runtime/RhConfig.h
new file mode 100644
index 000000000..4045db0b4
--- /dev/null
+++ b/src/Native/Runtime/RhConfig.h
@@ -0,0 +1,130 @@
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+//
+// Provides simple configuration support through environment variables. Each variable is lazily inspected on
+// first query and the resulting value cached for future use. To keep things simple we support reading only
+// 32-bit hex quantities and a zero value is considered equivalent to the environment variable not being
+// defined. We can get more sophisticated if needs be, but the hope is that very few configuration values are
+// exposed in this manner.
+//
+// Values can also be configured through an rhconfig.ini file. The file must be and ASCII text file, must be
+// placed next to the executing assembly, and be named rhconfig.ini. The file consists of one config entry per line
+// in the format: <Key>=<Value>
+// example:
+// RH_HeapVerify=1
+// RH_BreakOnAssert=1
+//
+
+
+#ifndef DACCESS_COMPILE
+
+#if defined(_DEBUG) || !defined(APP_LOCAL_RUNTIME)
+#define RH_ENVIRONMENT_VARIABLE_CONFIG_ENABLED
+#endif
+
+class RhConfig
+{
+
+#define CONFIG_INI_FILENAME L"rhconfig.ini"
+#define CONFIG_INI_NOT_AVAIL (void*)0x1 //signal for ini file failed to load
+#define CONFIG_KEY_MAXLEN 50 //arbitrary max length of config keys increase if needed
+#define CONFIG_VAL_MAXLEN 8 //32 bit uint in hex
+
+private:
+ struct ConfigPair
+ {
+ public:
+ WCHAR Key[CONFIG_KEY_MAXLEN + 1]; //maxlen + null terminator
+ WCHAR Value[CONFIG_VAL_MAXLEN + 1]; //maxlen + null terminator
+ };
+
+ //g_iniSettings is a buffer of ConfigPair structs which when initialized is of length RCV_Count
+ //the first N settings which are set in rhconfig.ini will be initialized and the remainder with have
+ //empty string "\0" as a Key and Value
+ //
+ //if the buffer has not been initialized (ie the ini file has not been read) the value will be NULL
+ //if we already attempted to initialize the file and could not find or read the contents the
+ //value will be CONFIG_INI_NOT_AVAIL to distinguish from the unitialized buffer.
+ //
+ //NOTE: g_iniSettings is only set in ReadConfigIni and must be set atomically only once
+ // using PalInterlockedCompareExchangePointer to avoid races when initializing
+private:
+ void* volatile g_iniSettings = NULL;
+
+public:
+
+#define DEFINE_VALUE_ACCESSOR(_name) \
+ UInt32 Get##_name() \
+ { \
+ if (m_uiConfigValuesRead & (1 << RCV_##_name)) \
+ return m_uiConfigValues[RCV_##_name]; \
+ UInt32 uiValue = ReadConfigValue(L"RH_" L ## #_name); \
+ m_uiConfigValues[RCV_##_name] = uiValue; \
+ m_uiConfigValuesRead |= 1 << RCV_##_name; \
+ return uiValue; \
+ }
+
+
+#ifdef _DEBUG
+#define DEBUG_CONFIG_VALUE(_name) DEFINE_VALUE_ACCESSOR(_name)
+#else
+#define DEBUG_CONFIG_VALUE(_name)
+#endif
+#define RETAIL_CONFIG_VALUE(_name) DEFINE_VALUE_ACCESSOR(_name)
+#include "RhConfigValues.h"
+#undef DEBUG_CONFIG_VALUE
+#undef RETAIL_CONFIG_VALUE
+
+private:
+
+ UInt32 ReadConfigValue(_In_z_ WCHAR *wszName);
+
+ enum RhConfigValue
+ {
+#define DEBUG_CONFIG_VALUE(_name) RCV_##_name,
+#define RETAIL_CONFIG_VALUE(_name) RCV_##_name,
+#include "RhConfigValues.h"
+#undef DEBUG_CONFIG_VALUE
+#undef RETAIL_CONFIG_VALUE
+ RCV_Count
+ };
+
+//accomidate for the maximum number of config values plus sizable buffer for whitespace 2K
+#define CONFIG_FILE_MAXLEN RCV_Count * sizeof(ConfigPair) + 2000
+
+private:
+ _Ret_maybenull_z_ WCHAR* RhConfig::GetConfigPath();
+
+ //Parses one line of rhconfig.ini and populates values in the passed in configPair
+ //returns: true if the parsing was successful, false if the parsing failed.
+ //NOTE: if the method fails configPair is left in an unitialized state
+ bool ParseConfigLine(_Out_ ConfigPair* configPair, _In_z_ const char * line);
+
+ //reads the configuration values from rhconfig.ini and updates g_iniSettings
+ //if the file is read succesfully and g_iniSettings will be set to a valid ConfigPair[] of length RCV_Count.
+ //if the file does not exist or reading the file fails, g_iniSettings is set to CONFIG_INI_NOT_AVAIL
+ //NOTE: all return paths must set g_iniSettings
+ void ReadConfigIni();
+
+ //reads a config value from rhconfig.ini into outputBuffer buffer returning the length of the value.
+ //lazily reads the file so if the file is not yet read, it will read it on first called
+ //if the file is not avaliable, or unreadable zero will always be returned
+ //cchOuputBuffer is the maximum number of characters to write to outputBuffer
+ UInt32 GetIniVariable(_In_z_ WCHAR* configName, _Out_writes_all_(cchBuff) WCHAR* outputBuffer, _In_ UInt32 cchOuputBuffer);
+
+ static bool priv_isspace(char c)
+ {
+ return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
+ }
+
+
+ UInt32 m_uiConfigValuesRead;
+ UInt32 m_uiConfigValues[RCV_Count];
+};
+
+extern RhConfig * g_pRhConfig;
+
+#endif //!DACCESS_COMPILE \ No newline at end of file