You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,235 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ClientConfigurationSystem.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Configuration {
|
||||
using System.Configuration.Internal;
|
||||
using System.Globalization;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using Assembly = System.Reflection.Assembly;
|
||||
using StringBuilder = System.Text.StringBuilder;
|
||||
|
||||
internal sealed class ClientConfigurationSystem : IInternalConfigSystem {
|
||||
private const string SystemDiagnosticsConfigKey = "system.diagnostics";
|
||||
private const string SystemNetGroupKey = "system.net/";
|
||||
|
||||
private IConfigSystem _configSystem;
|
||||
private IInternalConfigRoot _configRoot;
|
||||
private ClientConfigurationHost _configHost;
|
||||
private IInternalConfigRecord _machineConfigRecord;
|
||||
private IInternalConfigRecord _completeConfigRecord;
|
||||
private Exception _initError;
|
||||
private bool _isInitInProgress;
|
||||
private bool _isMachineConfigInited;
|
||||
private bool _isUserConfigInited;
|
||||
private bool _isAppConfigHttp;
|
||||
|
||||
|
||||
internal ClientConfigurationSystem() {
|
||||
_configSystem = new ConfigSystem();
|
||||
_configSystem.Init(typeof(ClientConfigurationHost), null, null);
|
||||
|
||||
_configHost = (ClientConfigurationHost) _configSystem.Host;
|
||||
_configRoot = _configSystem.Root;
|
||||
|
||||
_configRoot.ConfigRemoved += OnConfigRemoved;
|
||||
|
||||
_isAppConfigHttp = _configHost.IsAppConfigHttp;
|
||||
|
||||
// VSWhidbey 606116: Config has a dependency on Uri class which has
|
||||
// a new static constructor that calls config. We need a dummy reference
|
||||
// to Uri class so the static constructor would be involved first to
|
||||
// initialize config.
|
||||
string dummy = System.Uri.SchemeDelimiter;
|
||||
}
|
||||
|
||||
// Return true if the section might be used during initialization of the configuration system,
|
||||
// and thus lead to deadlock if appropriate measures are not taken.
|
||||
bool IsSectionUsedInInit(string configKey) {
|
||||
return configKey == SystemDiagnosticsConfigKey || (_isAppConfigHttp && configKey.StartsWith(SystemNetGroupKey, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
// Return true if the section should only use the machine configuration and not use the
|
||||
// application configuration. This is only true for system.net sections when the configuration
|
||||
// file for the application is downloaded via http using System.Net.WebClient.
|
||||
bool DoesSectionOnlyUseMachineConfig(string configKey) {
|
||||
return _isAppConfigHttp && configKey.StartsWith(SystemNetGroupKey, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
// Ensure that initialization has completed, while handling re-entrancy issues
|
||||
// for certain sections that may be used during initialization itself.
|
||||
void EnsureInit(string configKey) {
|
||||
bool doInit = false;
|
||||
|
||||
lock (this) {
|
||||
// If the user config is not initialized, then we must either:
|
||||
// a. Perform the initialization ourselves if no other thread is doing it, or
|
||||
// b. Wait for the initialization to complete if we know the section is not used during initialization itself, or
|
||||
// c. Ignore initialization if the section can be used during initialization. Note that GetSection()
|
||||
// returns null is initialization has not completed.
|
||||
if (!_isUserConfigInited) {
|
||||
if (!_isInitInProgress) {
|
||||
_isInitInProgress = true;
|
||||
doInit = true;
|
||||
}
|
||||
else if (!IsSectionUsedInInit(configKey)) {
|
||||
// Wait for initialization to complete.
|
||||
Monitor.Wait(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doInit) {
|
||||
try {
|
||||
try {
|
||||
try {
|
||||
// Initialize machine configuration.
|
||||
_machineConfigRecord = _configRoot.GetConfigRecord(
|
||||
ClientConfigurationHost.MachineConfigPath);
|
||||
|
||||
_machineConfigRecord.ThrowIfInitErrors();
|
||||
|
||||
// Make machine configuration available to system.net sections
|
||||
// when application configuration is downloaded via http.
|
||||
_isMachineConfigInited = true;
|
||||
|
||||
//
|
||||
// Prevent deadlocks in the networking classes by loading
|
||||
// networking config before making a networking request.
|
||||
// Any requests for sections used in initialization during
|
||||
// the call to EnsureConfigLoaded() will be served by
|
||||
// _machine.config or will return null.
|
||||
//
|
||||
if (_isAppConfigHttp) {
|
||||
ConfigurationManagerHelperFactory.Instance.EnsureNetConfigLoaded();
|
||||
}
|
||||
|
||||
//
|
||||
// Now load the rest of configuration
|
||||
//
|
||||
_configHost.RefreshConfigPaths();
|
||||
string configPath;
|
||||
if (_configHost.HasLocalConfig) {
|
||||
configPath = ClientConfigurationHost.LocalUserConfigPath;
|
||||
}
|
||||
else if (_configHost.HasRoamingConfig) {
|
||||
configPath = ClientConfigurationHost.RoamingUserConfigPath;
|
||||
}
|
||||
else {
|
||||
configPath = ClientConfigurationHost.ExeConfigPath;
|
||||
}
|
||||
|
||||
_completeConfigRecord = _configRoot.GetConfigRecord(configPath);
|
||||
_completeConfigRecord.ThrowIfInitErrors();
|
||||
|
||||
_isUserConfigInited = true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
_initError = new ConfigurationErrorsException(SR.GetString(SR.Config_client_config_init_error), e);
|
||||
throw _initError;
|
||||
}
|
||||
}
|
||||
catch {
|
||||
ConfigurationManager.SetInitError(_initError);
|
||||
_isMachineConfigInited = true;
|
||||
_isUserConfigInited = true;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock (this) {
|
||||
try {
|
||||
// Notify ConfigurationSettings that initialization has fully completed,
|
||||
// even if unsuccessful.
|
||||
ConfigurationManager.CompleteConfigInit();
|
||||
|
||||
_isInitInProgress = false;
|
||||
|
||||
}
|
||||
finally {
|
||||
// Wake up all threads waiting for initialization to complete.
|
||||
Monitor.PulseAll(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PrepareClientConfigSystem(string sectionName) {
|
||||
// Ensure the configuration system is inited for this section.
|
||||
if (!_isUserConfigInited) {
|
||||
EnsureInit(sectionName);
|
||||
}
|
||||
|
||||
// If an error occurred during initialzation, throw it.
|
||||
if (_initError != null) {
|
||||
throw _initError;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If config has been removed because initialization was not complete,
|
||||
// fetch a new configuration record. The record will be created and
|
||||
// completely initialized as RequireCompleteInit() will have been called
|
||||
// on the ClientConfigurationHost before we receive this event.
|
||||
//
|
||||
private void OnConfigRemoved(object sender, InternalConfigEventArgs e) {
|
||||
try {
|
||||
IInternalConfigRecord newConfigRecord = _configRoot.GetConfigRecord(_completeConfigRecord.ConfigPath);
|
||||
_completeConfigRecord = newConfigRecord;
|
||||
_completeConfigRecord.ThrowIfInitErrors();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
_initError = new ConfigurationErrorsException(SR.GetString(SR.Config_client_config_init_error), ex);
|
||||
ConfigurationManager.SetInitError(_initError);
|
||||
throw _initError;
|
||||
}
|
||||
}
|
||||
|
||||
object IInternalConfigSystem.GetSection(string sectionName) {
|
||||
PrepareClientConfigSystem(sectionName);
|
||||
|
||||
// Get the appropriate config record for the section.
|
||||
IInternalConfigRecord configRecord = null;
|
||||
if (DoesSectionOnlyUseMachineConfig(sectionName)) {
|
||||
if (_isMachineConfigInited) {
|
||||
configRecord = _machineConfigRecord;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (_isUserConfigInited) {
|
||||
configRecord = _completeConfigRecord;
|
||||
}
|
||||
}
|
||||
|
||||
// Call GetSection(), or return null if no configuration is yet available.
|
||||
if (configRecord != null) {
|
||||
return configRecord.GetSection(sectionName);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void IInternalConfigSystem.RefreshConfig(string sectionName) {
|
||||
PrepareClientConfigSystem(sectionName);
|
||||
|
||||
if (_isMachineConfigInited) {
|
||||
_machineConfigRecord.RefreshSection(sectionName);
|
||||
}
|
||||
}
|
||||
|
||||
// Supports user config
|
||||
bool IInternalConfigSystem.SupportsUserConfig {
|
||||
get {return true;}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user