Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Configuration / System / Configuration / Internal / InternalConfigRoot.cs / 1305376 / InternalConfigRoot.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Configuration.Internal { using System.Configuration.Internal; using System.Collections; using System.Collections.Specialized; using System.Configuration; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Security; using System.Text; using System.Xml; using System.Threading; // // InternalConfigRoot holds the root of a configuration hierarchy. // It managed creation, removal, and the search for BaseConfigurationRecord's. // in a thread-safe manner. // // The BaseConfigurationRecord hierarchy is protected with the // _hierarchyLock. Functions that assume that the lock as been // taken begin with the prefix "hl", for example, "hlFindConfigRecord". // internal sealed class InternalConfigRoot : IInternalConfigRoot { IInternalConfigHost _host; // host, need to create records ReaderWriterLock _hierarchyLock; // lock to protect hierarchy BaseConfigurationRecord _rootConfigRecord; // root config record, one level above machine.config. bool _isDesignTime; // Is the hierarchy for runtime or designtime? private Configuration _CurrentConfiguration = null; public event InternalConfigEventHandler ConfigChanged; public event InternalConfigEventHandler ConfigRemoved; internal InternalConfigRoot() { } internal InternalConfigRoot(Configuration currentConfiguration) { _CurrentConfiguration = currentConfiguration; } void IInternalConfigRoot.Init(IInternalConfigHost host, bool isDesignTime) { _host = host; _isDesignTime = isDesignTime; _hierarchyLock = new ReaderWriterLock(); // Dummy record to hold _children for root if (_isDesignTime) { _rootConfigRecord = MgmtConfigurationRecord.Create(this, null, string.Empty, null); } else { _rootConfigRecord = (BaseConfigurationRecord) RuntimeConfigurationRecord.Create(this, null, string.Empty); } } internal IInternalConfigHost Host { get {return _host;} } internal BaseConfigurationRecord RootConfigRecord { get {return _rootConfigRecord;} } bool IInternalConfigRoot.IsDesignTime { get {return _isDesignTime;} } private void AcquireHierarchyLockForRead() { // Protect against unexpected recursive entry on this thread. // We do this in retail, too, because the results would be very bad if this were to fail, // and the testing for this is not easy for all scenarios. Debug.Assert(!_hierarchyLock.IsReaderLockHeld, "!_hierarchyLock.IsReaderLockHeld"); if (_hierarchyLock.IsReaderLockHeld) { throw ExceptionUtil.UnexpectedError("System.Configuration.Internal.InternalConfigRoot::AcquireHierarchyLockForRead - reader lock already held by this thread"); } Debug.Assert(!_hierarchyLock.IsWriterLockHeld, "!_hierarchyLock.IsWriterLockHeld"); if (_hierarchyLock.IsWriterLockHeld) { throw ExceptionUtil.UnexpectedError("System.Configuration.Internal.InternalConfigRoot::AcquireHierarchyLockForRead - writer lock already held by this thread"); } _hierarchyLock.AcquireReaderLock(-1); } private void ReleaseHierarchyLockForRead() { Debug.Assert(!_hierarchyLock.IsWriterLockHeld, "!_hierarchyLock.IsWriterLockHeld"); if (_hierarchyLock.IsReaderLockHeld) { _hierarchyLock.ReleaseReaderLock(); } } private void AcquireHierarchyLockForWrite() { // Protect against unexpected recursive entry on this thread. // We do this in retail, too, because the results would be very bad if this were to fail, // and the testing for this is not easy for all scenarios. if (_hierarchyLock.IsReaderLockHeld) { throw ExceptionUtil.UnexpectedError("System.Configuration.Internal.InternalConfigRoot::AcquireHierarchyLockForWrite - reader lock already held by this thread"); } if (_hierarchyLock.IsWriterLockHeld) { throw ExceptionUtil.UnexpectedError("System.Configuration.Internal.InternalConfigRoot::AcquireHierarchyLockForWrite - writer lock already held by this thread"); } _hierarchyLock.AcquireWriterLock(-1); } private void ReleaseHierarchyLockForWrite() { Debug.Assert(!_hierarchyLock.IsReaderLockHeld, "!_hierarchyLock.IsReaderLockHeld"); if (_hierarchyLock.IsWriterLockHeld) { _hierarchyLock.ReleaseWriterLock(); } } // // Find a config record. // If found, nextIndex == parts.Length and the resulting record is in currentRecord. // If not found, nextIndex is the index of the part of the path not found, and currentRecord // is the record that has been found so far (nexIndex - 1). // private void hlFindConfigRecord(string[] parts, out int nextIndex, out BaseConfigurationRecord currentRecord) { currentRecord = _rootConfigRecord; nextIndex = 0; for (; nextIndex < parts.Length; nextIndex++) { BaseConfigurationRecord childRecord = currentRecord.hlGetChild(parts[nextIndex]); if (childRecord == null) break; currentRecord = childRecord; } } // // Get a config section. // public object GetSection(string section, string configPath) { BaseConfigurationRecord configRecord = (BaseConfigurationRecord) GetUniqueConfigRecord(configPath); object result = configRecord.GetSection(section); return result; } // // Get the nearest ancestor path (including self) which contains unique configuration information. // public string GetUniqueConfigPath(string configPath) { IInternalConfigRecord configRecord = GetUniqueConfigRecord(configPath); if (configRecord == null) { return null; } return configRecord.ConfigPath; } // // Get the nearest ancestor record (including self) which contains unique configuration information. // public IInternalConfigRecord GetUniqueConfigRecord(string configPath) { BaseConfigurationRecord configRecord = (BaseConfigurationRecord) GetConfigRecord(configPath); while (configRecord.IsEmpty) { BaseConfigurationRecord parentConfigRecord = configRecord.Parent; // If all config records are empty, return the immediate child of the // root placeholder (e.g. machine.config) if (parentConfigRecord.IsRootConfig) { break; } configRecord = parentConfigRecord; } return configRecord; } // // Get the config record for a path. // If the record does not exist, create it if it is needed. // public IInternalConfigRecord GetConfigRecord(string configPath) { if (!ConfigPathUtility.IsValid(configPath)) { throw ExceptionUtil.ParameterInvalid("configPath"); } string[] parts = ConfigPathUtility.GetParts(configPath); // // First search under the reader lock, so that multiple searches // can proceed in parallel. // try { int index; BaseConfigurationRecord currentRecord; AcquireHierarchyLockForRead(); hlFindConfigRecord(parts, out index, out currentRecord); // check if found if (index == parts.Length || !currentRecord.hlNeedsChildFor(parts[index])) { return currentRecord; } } finally { ReleaseHierarchyLockForRead(); } // // Not found, so search again under exclusive writer lock so that // we can create the record. // try { int index; BaseConfigurationRecord currentRecord; AcquireHierarchyLockForWrite(); hlFindConfigRecord(parts, out index, out currentRecord); if (index == parts.Length) { return currentRecord; } string currentConfigPath = String.Join(BaseConfigurationRecord.ConfigPathSeparatorString, parts, 0, index); // // create new records // while (index < parts.Length && currentRecord.hlNeedsChildFor(parts[index])) { string configName = parts[index]; currentConfigPath = ConfigPathUtility.Combine(currentConfigPath, configName); BaseConfigurationRecord childRecord; Debug.Trace("ConfigurationCreate", "Creating config record for " + currentConfigPath); if (_isDesignTime) { childRecord = MgmtConfigurationRecord.Create(this, currentRecord, currentConfigPath, null); } else { childRecord = (BaseConfigurationRecord) RuntimeConfigurationRecord.Create(this, currentRecord, currentConfigPath); } currentRecord.hlAddChild(configName, childRecord); index++; currentRecord = childRecord; } return currentRecord; } finally { ReleaseHierarchyLockForWrite(); } } // // Find and remove the config record and all its children for the config path. // Optionally ensure the config record matches a desired config record. // void RemoveConfigImpl(string configPath, BaseConfigurationRecord configRecord) { if (!ConfigPathUtility.IsValid(configPath)) { throw ExceptionUtil.ParameterInvalid("configPath"); } string[] parts = ConfigPathUtility.GetParts(configPath); BaseConfigurationRecord currentRecord; // search under exclusive writer lock try { int index; AcquireHierarchyLockForWrite(); hlFindConfigRecord(parts, out index, out currentRecord); // Return if not found, or does not match the one we are trying to remove. if (index != parts.Length || (configRecord != null && !Object.ReferenceEquals(configRecord, currentRecord))) return; // Remove it from the hierarchy. currentRecord.Parent.hlRemoveChild(parts[parts.Length - 1]); } finally { ReleaseHierarchyLockForWrite(); } OnConfigRemoved(new InternalConfigEventArgs(configPath)); // Close the record. This is safe to do outside the lock. currentRecord.CloseRecursive(); } // // Find and remove the config record and all its children for the config path. // public void RemoveConfig(string configPath) { RemoveConfigImpl(configPath, null); } // // Remove the config record and all its children for the config path. // public void RemoveConfigRecord(BaseConfigurationRecord configRecord) { RemoveConfigImpl(configRecord.ConfigPath, configRecord); } // // Clear the result of a configSection evaluation at a particular point // in the hierarchy. // public void ClearResult(BaseConfigurationRecord configRecord, string configKey, bool forceEvaluation) { string[] parts = ConfigPathUtility.GetParts(configRecord.ConfigPath); try { int index; BaseConfigurationRecord currentRecord; AcquireHierarchyLockForRead(); hlFindConfigRecord(parts, out index, out currentRecord); // clear result only if configRecord it is still in the hierarchy if (index == parts.Length && Object.ReferenceEquals(configRecord, currentRecord)) { currentRecord.hlClearResultRecursive(configKey, forceEvaluation); } } finally { ReleaseHierarchyLockForRead(); } } // Fire the ConfigRemoved event. private void OnConfigRemoved(InternalConfigEventArgs e) { InternalConfigEventHandler handler = ConfigRemoved; if (handler != null) { handler(this, e); } } // Fire the ConfigChanged event for a configPath. internal void FireConfigChanged(string configPath) { OnConfigChanged(new InternalConfigEventArgs(configPath)); } // Fire the ConfigChanged event. private void OnConfigChanged(InternalConfigEventArgs e) { InternalConfigEventHandler handler = ConfigChanged; if (handler != null) { handler(this, e); } } internal Configuration CurrentConfiguration { get { return _CurrentConfiguration; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Configuration.Internal { using System.Configuration.Internal; using System.Collections; using System.Collections.Specialized; using System.Configuration; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Security; using System.Text; using System.Xml; using System.Threading; // // InternalConfigRoot holds the root of a configuration hierarchy. // It managed creation, removal, and the search for BaseConfigurationRecord's. // in a thread-safe manner. // // The BaseConfigurationRecord hierarchy is protected with the // _hierarchyLock. Functions that assume that the lock as been // taken begin with the prefix "hl", for example, "hlFindConfigRecord". // internal sealed class InternalConfigRoot : IInternalConfigRoot { IInternalConfigHost _host; // host, need to create records ReaderWriterLock _hierarchyLock; // lock to protect hierarchy BaseConfigurationRecord _rootConfigRecord; // root config record, one level above machine.config. bool _isDesignTime; // Is the hierarchy for runtime or designtime? private Configuration _CurrentConfiguration = null; public event InternalConfigEventHandler ConfigChanged; public event InternalConfigEventHandler ConfigRemoved; internal InternalConfigRoot() { } internal InternalConfigRoot(Configuration currentConfiguration) { _CurrentConfiguration = currentConfiguration; } void IInternalConfigRoot.Init(IInternalConfigHost host, bool isDesignTime) { _host = host; _isDesignTime = isDesignTime; _hierarchyLock = new ReaderWriterLock(); // Dummy record to hold _children for root if (_isDesignTime) { _rootConfigRecord = MgmtConfigurationRecord.Create(this, null, string.Empty, null); } else { _rootConfigRecord = (BaseConfigurationRecord) RuntimeConfigurationRecord.Create(this, null, string.Empty); } } internal IInternalConfigHost Host { get {return _host;} } internal BaseConfigurationRecord RootConfigRecord { get {return _rootConfigRecord;} } bool IInternalConfigRoot.IsDesignTime { get {return _isDesignTime;} } private void AcquireHierarchyLockForRead() { // Protect against unexpected recursive entry on this thread. // We do this in retail, too, because the results would be very bad if this were to fail, // and the testing for this is not easy for all scenarios. Debug.Assert(!_hierarchyLock.IsReaderLockHeld, "!_hierarchyLock.IsReaderLockHeld"); if (_hierarchyLock.IsReaderLockHeld) { throw ExceptionUtil.UnexpectedError("System.Configuration.Internal.InternalConfigRoot::AcquireHierarchyLockForRead - reader lock already held by this thread"); } Debug.Assert(!_hierarchyLock.IsWriterLockHeld, "!_hierarchyLock.IsWriterLockHeld"); if (_hierarchyLock.IsWriterLockHeld) { throw ExceptionUtil.UnexpectedError("System.Configuration.Internal.InternalConfigRoot::AcquireHierarchyLockForRead - writer lock already held by this thread"); } _hierarchyLock.AcquireReaderLock(-1); } private void ReleaseHierarchyLockForRead() { Debug.Assert(!_hierarchyLock.IsWriterLockHeld, "!_hierarchyLock.IsWriterLockHeld"); if (_hierarchyLock.IsReaderLockHeld) { _hierarchyLock.ReleaseReaderLock(); } } private void AcquireHierarchyLockForWrite() { // Protect against unexpected recursive entry on this thread. // We do this in retail, too, because the results would be very bad if this were to fail, // and the testing for this is not easy for all scenarios. if (_hierarchyLock.IsReaderLockHeld) { throw ExceptionUtil.UnexpectedError("System.Configuration.Internal.InternalConfigRoot::AcquireHierarchyLockForWrite - reader lock already held by this thread"); } if (_hierarchyLock.IsWriterLockHeld) { throw ExceptionUtil.UnexpectedError("System.Configuration.Internal.InternalConfigRoot::AcquireHierarchyLockForWrite - writer lock already held by this thread"); } _hierarchyLock.AcquireWriterLock(-1); } private void ReleaseHierarchyLockForWrite() { Debug.Assert(!_hierarchyLock.IsReaderLockHeld, "!_hierarchyLock.IsReaderLockHeld"); if (_hierarchyLock.IsWriterLockHeld) { _hierarchyLock.ReleaseWriterLock(); } } // // Find a config record. // If found, nextIndex == parts.Length and the resulting record is in currentRecord. // If not found, nextIndex is the index of the part of the path not found, and currentRecord // is the record that has been found so far (nexIndex - 1). // private void hlFindConfigRecord(string[] parts, out int nextIndex, out BaseConfigurationRecord currentRecord) { currentRecord = _rootConfigRecord; nextIndex = 0; for (; nextIndex < parts.Length; nextIndex++) { BaseConfigurationRecord childRecord = currentRecord.hlGetChild(parts[nextIndex]); if (childRecord == null) break; currentRecord = childRecord; } } // // Get a config section. // public object GetSection(string section, string configPath) { BaseConfigurationRecord configRecord = (BaseConfigurationRecord) GetUniqueConfigRecord(configPath); object result = configRecord.GetSection(section); return result; } // // Get the nearest ancestor path (including self) which contains unique configuration information. // public string GetUniqueConfigPath(string configPath) { IInternalConfigRecord configRecord = GetUniqueConfigRecord(configPath); if (configRecord == null) { return null; } return configRecord.ConfigPath; } // // Get the nearest ancestor record (including self) which contains unique configuration information. // public IInternalConfigRecord GetUniqueConfigRecord(string configPath) { BaseConfigurationRecord configRecord = (BaseConfigurationRecord) GetConfigRecord(configPath); while (configRecord.IsEmpty) { BaseConfigurationRecord parentConfigRecord = configRecord.Parent; // If all config records are empty, return the immediate child of the // root placeholder (e.g. machine.config) if (parentConfigRecord.IsRootConfig) { break; } configRecord = parentConfigRecord; } return configRecord; } // // Get the config record for a path. // If the record does not exist, create it if it is needed. // public IInternalConfigRecord GetConfigRecord(string configPath) { if (!ConfigPathUtility.IsValid(configPath)) { throw ExceptionUtil.ParameterInvalid("configPath"); } string[] parts = ConfigPathUtility.GetParts(configPath); // // First search under the reader lock, so that multiple searches // can proceed in parallel. // try { int index; BaseConfigurationRecord currentRecord; AcquireHierarchyLockForRead(); hlFindConfigRecord(parts, out index, out currentRecord); // check if found if (index == parts.Length || !currentRecord.hlNeedsChildFor(parts[index])) { return currentRecord; } } finally { ReleaseHierarchyLockForRead(); } // // Not found, so search again under exclusive writer lock so that // we can create the record. // try { int index; BaseConfigurationRecord currentRecord; AcquireHierarchyLockForWrite(); hlFindConfigRecord(parts, out index, out currentRecord); if (index == parts.Length) { return currentRecord; } string currentConfigPath = String.Join(BaseConfigurationRecord.ConfigPathSeparatorString, parts, 0, index); // // create new records // while (index < parts.Length && currentRecord.hlNeedsChildFor(parts[index])) { string configName = parts[index]; currentConfigPath = ConfigPathUtility.Combine(currentConfigPath, configName); BaseConfigurationRecord childRecord; Debug.Trace("ConfigurationCreate", "Creating config record for " + currentConfigPath); if (_isDesignTime) { childRecord = MgmtConfigurationRecord.Create(this, currentRecord, currentConfigPath, null); } else { childRecord = (BaseConfigurationRecord) RuntimeConfigurationRecord.Create(this, currentRecord, currentConfigPath); } currentRecord.hlAddChild(configName, childRecord); index++; currentRecord = childRecord; } return currentRecord; } finally { ReleaseHierarchyLockForWrite(); } } // // Find and remove the config record and all its children for the config path. // Optionally ensure the config record matches a desired config record. // void RemoveConfigImpl(string configPath, BaseConfigurationRecord configRecord) { if (!ConfigPathUtility.IsValid(configPath)) { throw ExceptionUtil.ParameterInvalid("configPath"); } string[] parts = ConfigPathUtility.GetParts(configPath); BaseConfigurationRecord currentRecord; // search under exclusive writer lock try { int index; AcquireHierarchyLockForWrite(); hlFindConfigRecord(parts, out index, out currentRecord); // Return if not found, or does not match the one we are trying to remove. if (index != parts.Length || (configRecord != null && !Object.ReferenceEquals(configRecord, currentRecord))) return; // Remove it from the hierarchy. currentRecord.Parent.hlRemoveChild(parts[parts.Length - 1]); } finally { ReleaseHierarchyLockForWrite(); } OnConfigRemoved(new InternalConfigEventArgs(configPath)); // Close the record. This is safe to do outside the lock. currentRecord.CloseRecursive(); } // // Find and remove the config record and all its children for the config path. // public void RemoveConfig(string configPath) { RemoveConfigImpl(configPath, null); } // // Remove the config record and all its children for the config path. // public void RemoveConfigRecord(BaseConfigurationRecord configRecord) { RemoveConfigImpl(configRecord.ConfigPath, configRecord); } // // Clear the result of a configSection evaluation at a particular point // in the hierarchy. // public void ClearResult(BaseConfigurationRecord configRecord, string configKey, bool forceEvaluation) { string[] parts = ConfigPathUtility.GetParts(configRecord.ConfigPath); try { int index; BaseConfigurationRecord currentRecord; AcquireHierarchyLockForRead(); hlFindConfigRecord(parts, out index, out currentRecord); // clear result only if configRecord it is still in the hierarchy if (index == parts.Length && Object.ReferenceEquals(configRecord, currentRecord)) { currentRecord.hlClearResultRecursive(configKey, forceEvaluation); } } finally { ReleaseHierarchyLockForRead(); } } // Fire the ConfigRemoved event. private void OnConfigRemoved(InternalConfigEventArgs e) { InternalConfigEventHandler handler = ConfigRemoved; if (handler != null) { handler(this, e); } } // Fire the ConfigChanged event for a configPath. internal void FireConfigChanged(string configPath) { OnConfigChanged(new InternalConfigEventArgs(configPath)); } // Fire the ConfigChanged event. private void OnConfigChanged(InternalConfigEventArgs e) { InternalConfigEventHandler handler = ConfigChanged; if (handler != null) { handler(this, e); } } internal Configuration CurrentConfiguration { get { return _CurrentConfiguration; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ButtonRenderer.cs
- SqlCrossApplyToCrossJoin.cs
- NativeObjectSecurity.cs
- BuilderElements.cs
- documentsequencetextpointer.cs
- Button.cs
- ReferencedAssembly.cs
- GroupItemAutomationPeer.cs
- ValidationException.cs
- UpWmlMobileTextWriter.cs
- MouseEventArgs.cs
- DateTimeConverter2.cs
- BamlLocalizableResourceKey.cs
- LateBoundBitmapDecoder.cs
- PropertySegmentSerializationProvider.cs
- SlotInfo.cs
- TableCellCollection.cs
- SrgsDocumentParser.cs
- TablePattern.cs
- SessionStateItemCollection.cs
- GAC.cs
- XmlDataSourceView.cs
- IApplicationTrustManager.cs
- XamlSerializer.cs
- DefaultIfEmptyQueryOperator.cs
- ReadContentAsBinaryHelper.cs
- AnnotationResourceChangedEventArgs.cs
- XmlCDATASection.cs
- XMLSyntaxException.cs
- DecimalAverageAggregationOperator.cs
- ContextMenu.cs
- BulletChrome.cs
- SQLMoneyStorage.cs
- MimeMapping.cs
- SubpageParaClient.cs
- InkPresenter.cs
- HttpContextServiceHost.cs
- AudienceUriMode.cs
- Light.cs
- StringUtil.cs
- Icon.cs
- TypeName.cs
- ComponentChangedEvent.cs
- EntityClientCacheKey.cs
- ClockGroup.cs
- RoleManagerEventArgs.cs
- BitmapEffectInputConnector.cs
- Substitution.cs
- XhtmlConformanceSection.cs
- CapabilitiesPattern.cs
- X509CertificateTokenFactoryCredential.cs
- COM2ExtendedBrowsingHandler.cs
- WebPartConnectionsCancelVerb.cs
- ConnectionStringsExpressionBuilder.cs
- HostProtectionPermission.cs
- PrivateUnsafeNativeCompoundFileMethods.cs
- CollectionChangeEventArgs.cs
- safePerfProviderHandle.cs
- AxWrapperGen.cs
- ListViewTableRow.cs
- Polygon.cs
- InstanceCreationEditor.cs
- VariableQuery.cs
- CodeTypeMemberCollection.cs
- Stylesheet.cs
- DataGridViewCellStyleContentChangedEventArgs.cs
- ReadWriteSpinLock.cs
- PointUtil.cs
- StorageEndPropertyMapping.cs
- XmlNodeList.cs
- BookmarkInfo.cs
- DataControlImageButton.cs
- WebPartsSection.cs
- CalendarTable.cs
- FigureHelper.cs
- GridLength.cs
- ForeignConstraint.cs
- ErrorsHelper.cs
- HttpPostedFile.cs
- AttachedProperty.cs
- EditingMode.cs
- MultiBindingExpression.cs
- Pens.cs
- MemberListBinding.cs
- CheckoutException.cs
- JsonStringDataContract.cs
- FileDetails.cs
- ClassImporter.cs
- SpAudioStreamWrapper.cs
- WindowsListBox.cs
- FileDialog.cs
- XPathBinder.cs
- RecordManager.cs
- xmlsaver.cs
- HuffmanTree.cs
- SelectionChangedEventArgs.cs
- OdbcConnectionString.cs
- DbDeleteCommandTree.cs
- XmlElementAttributes.cs
- DBNull.cs