Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / _LocalDataStore.cs / 1305376 / _LocalDataStore.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================================== ** ** Class: LocalDataStore ** ** ** Purpose: Class that stores local data. This class is used in cooperation ** with the _LocalDataStoreMgr class. ** ** =============================================================================*/ namespace System { using System; using System.Threading; using System.Runtime.CompilerServices; using System.Diagnostics.Contracts; // Helper class to aid removal of LocalDataStore from the LocalDataStoreMgr // LocalDataStoreMgr does not holds references to LocalDataStoreHolder. It holds // references to LocalDataStore only. LocalDataStoreHolder finalizer will run once // the only outstanding reference to the store is in LocalDataStoreMgr. sealed internal class LocalDataStoreHolder { private LocalDataStore m_Store; public LocalDataStoreHolder(LocalDataStore store) { m_Store = store; } ~LocalDataStoreHolder() { LocalDataStore store = m_Store; if (store == null) return; store.Dispose(); } public LocalDataStore Store { get { return m_Store; } } } sealed internal class LocalDataStoreElement { private Object m_value; private long m_cookie; // This is immutable cookie of the slot used to verify that // the value is indeed indeed owned by the slot. Necessary // to avoid resurection holes. public LocalDataStoreElement(long cookie) { m_cookie = cookie; } public Object Value { get { return m_value; } set { m_value = value; } } public long Cookie { get { return m_cookie; } } } // This class will not be marked serializable sealed internal class LocalDataStore { private LocalDataStoreElement[] m_DataTable; private LocalDataStoreMgr m_Manager; /*========================================================================= ** Initialize the data store. =========================================================================*/ public LocalDataStore(LocalDataStoreMgr mgr, int InitialCapacity) { // Store the manager of the local data store. m_Manager = mgr; // Allocate the array that will contain the data. m_DataTable = new LocalDataStoreElement[InitialCapacity]; } /*========================================================================= ** Delete this store from its manager =========================================================================*/ internal void Dispose() { m_Manager.DeleteLocalDataStore(this); } /*========================================================================= ** Retrieves the value from the specified slot. =========================================================================*/ public Object GetData(LocalDataStoreSlot slot) { // Validate the slot. m_Manager.ValidateSlot(slot); // Cache the slot index to avoid synchronization issues. int slotIdx = slot.Slot; if (slotIdx >= 0) { // Delay expansion of m_DataTable if we can if (slotIdx >= m_DataTable.Length) return null; // Retrieve the data from the given slot. LocalDataStoreElement element = m_DataTable[slotIdx]; //Initially we prepopulate the elements to be null. if (element == null) return null; // Check that the element is owned by this slot by comparing cookies. // This is necesary to avoid resurection ----s. if (element.Cookie == slot.Cookie) return element.Value; // Fall thru and throw exception } throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed")); } /*========================================================================== ** Sets the data in the specified slot. =========================================================================*/ public void SetData(LocalDataStoreSlot slot, Object data) { // Validate the slot. m_Manager.ValidateSlot(slot); // Cache the slot index to avoid synchronization issues. int slotIdx = slot.Slot; if (slotIdx >= 0) { LocalDataStoreElement element = (slotIdx < m_DataTable.Length) ? m_DataTable[slotIdx] : null; if (element == null) { element = PopulateElement(slot); } // Check that the element is owned by this slot by comparing cookies. // This is necesary to avoid resurection ----s. if (element.Cookie == slot.Cookie) { // Set the data on the given slot. element.Value = data; return; } // Fall thru and throw exception } throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed")); } /*========================================================================= ** This method does clears the unused slot. * Assumes lock on m_Manager is taken =========================================================================*/ internal void FreeData(int slot, long cookie) { // We try to delay allocate the dataTable (in cases like the manager clearing a // just-freed slot in all stores if (slot >= m_DataTable.Length) return; LocalDataStoreElement element = m_DataTable[slot]; if (element != null && element.Cookie == cookie) m_DataTable[slot] = null; } /*========================================================================== ** Method used to expand the capacity of the local data store. =========================================================================*/ [System.Security.SecuritySafeCritical] // auto-generated private LocalDataStoreElement PopulateElement(LocalDataStoreSlot slot) { bool tookLock = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.Enter(m_Manager, ref tookLock); // Make sure that the slot was not freed in the meantime int slotIdx = slot.Slot; if (slotIdx < 0) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed")); if (slotIdx >= m_DataTable.Length) { int capacity = m_Manager.GetSlotTableLength(); // Validate that the specified capacity is larger than the current one. Contract.Assert(capacity >= m_DataTable.Length, "LocalDataStore corrupted: capacity >= m_DataTable.Length"); // Allocate the new data table. LocalDataStoreElement[] NewDataTable = new LocalDataStoreElement[capacity]; // Copy all the objects into the new table. Array.Copy(m_DataTable, NewDataTable, m_DataTable.Length); // Save the new table. m_DataTable = NewDataTable; } // Validate that there is enough space in the local data store now Contract.Assert(slotIdx < m_DataTable.Length, "LocalDataStore corrupted: slotIdx < m_DataTable.Length"); if (m_DataTable[slotIdx] == null) m_DataTable[slotIdx] = new LocalDataStoreElement(slot.Cookie); return m_DataTable[slotIdx]; } finally { if (tookLock) Monitor.Exit(m_Manager); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================================== ** ** Class: LocalDataStore ** ** ** Purpose: Class that stores local data. This class is used in cooperation ** with the _LocalDataStoreMgr class. ** ** =============================================================================*/ namespace System { using System; using System.Threading; using System.Runtime.CompilerServices; using System.Diagnostics.Contracts; // Helper class to aid removal of LocalDataStore from the LocalDataStoreMgr // LocalDataStoreMgr does not holds references to LocalDataStoreHolder. It holds // references to LocalDataStore only. LocalDataStoreHolder finalizer will run once // the only outstanding reference to the store is in LocalDataStoreMgr. sealed internal class LocalDataStoreHolder { private LocalDataStore m_Store; public LocalDataStoreHolder(LocalDataStore store) { m_Store = store; } ~LocalDataStoreHolder() { LocalDataStore store = m_Store; if (store == null) return; store.Dispose(); } public LocalDataStore Store { get { return m_Store; } } } sealed internal class LocalDataStoreElement { private Object m_value; private long m_cookie; // This is immutable cookie of the slot used to verify that // the value is indeed indeed owned by the slot. Necessary // to avoid resurection holes. public LocalDataStoreElement(long cookie) { m_cookie = cookie; } public Object Value { get { return m_value; } set { m_value = value; } } public long Cookie { get { return m_cookie; } } } // This class will not be marked serializable sealed internal class LocalDataStore { private LocalDataStoreElement[] m_DataTable; private LocalDataStoreMgr m_Manager; /*========================================================================= ** Initialize the data store. =========================================================================*/ public LocalDataStore(LocalDataStoreMgr mgr, int InitialCapacity) { // Store the manager of the local data store. m_Manager = mgr; // Allocate the array that will contain the data. m_DataTable = new LocalDataStoreElement[InitialCapacity]; } /*========================================================================= ** Delete this store from its manager =========================================================================*/ internal void Dispose() { m_Manager.DeleteLocalDataStore(this); } /*========================================================================= ** Retrieves the value from the specified slot. =========================================================================*/ public Object GetData(LocalDataStoreSlot slot) { // Validate the slot. m_Manager.ValidateSlot(slot); // Cache the slot index to avoid synchronization issues. int slotIdx = slot.Slot; if (slotIdx >= 0) { // Delay expansion of m_DataTable if we can if (slotIdx >= m_DataTable.Length) return null; // Retrieve the data from the given slot. LocalDataStoreElement element = m_DataTable[slotIdx]; //Initially we prepopulate the elements to be null. if (element == null) return null; // Check that the element is owned by this slot by comparing cookies. // This is necesary to avoid resurection ----s. if (element.Cookie == slot.Cookie) return element.Value; // Fall thru and throw exception } throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed")); } /*========================================================================== ** Sets the data in the specified slot. =========================================================================*/ public void SetData(LocalDataStoreSlot slot, Object data) { // Validate the slot. m_Manager.ValidateSlot(slot); // Cache the slot index to avoid synchronization issues. int slotIdx = slot.Slot; if (slotIdx >= 0) { LocalDataStoreElement element = (slotIdx < m_DataTable.Length) ? m_DataTable[slotIdx] : null; if (element == null) { element = PopulateElement(slot); } // Check that the element is owned by this slot by comparing cookies. // This is necesary to avoid resurection ----s. if (element.Cookie == slot.Cookie) { // Set the data on the given slot. element.Value = data; return; } // Fall thru and throw exception } throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed")); } /*========================================================================= ** This method does clears the unused slot. * Assumes lock on m_Manager is taken =========================================================================*/ internal void FreeData(int slot, long cookie) { // We try to delay allocate the dataTable (in cases like the manager clearing a // just-freed slot in all stores if (slot >= m_DataTable.Length) return; LocalDataStoreElement element = m_DataTable[slot]; if (element != null && element.Cookie == cookie) m_DataTable[slot] = null; } /*========================================================================== ** Method used to expand the capacity of the local data store. =========================================================================*/ [System.Security.SecuritySafeCritical] // auto-generated private LocalDataStoreElement PopulateElement(LocalDataStoreSlot slot) { bool tookLock = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.Enter(m_Manager, ref tookLock); // Make sure that the slot was not freed in the meantime int slotIdx = slot.Slot; if (slotIdx < 0) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed")); if (slotIdx >= m_DataTable.Length) { int capacity = m_Manager.GetSlotTableLength(); // Validate that the specified capacity is larger than the current one. Contract.Assert(capacity >= m_DataTable.Length, "LocalDataStore corrupted: capacity >= m_DataTable.Length"); // Allocate the new data table. LocalDataStoreElement[] NewDataTable = new LocalDataStoreElement[capacity]; // Copy all the objects into the new table. Array.Copy(m_DataTable, NewDataTable, m_DataTable.Length); // Save the new table. m_DataTable = NewDataTable; } // Validate that there is enough space in the local data store now Contract.Assert(slotIdx < m_DataTable.Length, "LocalDataStore corrupted: slotIdx < m_DataTable.Length"); if (m_DataTable[slotIdx] == null) m_DataTable[slotIdx] = new LocalDataStoreElement(slot.Cookie); return m_DataTable[slotIdx]; } finally { if (tookLock) Monitor.Exit(m_Manager); } } } } // 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
- BrowserTree.cs
- WorkItem.cs
- FilterableAttribute.cs
- SevenBitStream.cs
- DataObjectPastingEventArgs.cs
- EntityException.cs
- TableLayoutPanelBehavior.cs
- HandleCollector.cs
- DnsPermission.cs
- GeometryCollection.cs
- CompilerScope.cs
- TrueReadOnlyCollection.cs
- DeviceContexts.cs
- FlowDocumentPaginator.cs
- SnapLine.cs
- SequenceNumber.cs
- mactripleDES.cs
- SmtpDigestAuthenticationModule.cs
- XmlRawWriter.cs
- SystemIPGlobalStatistics.cs
- RegistrationServices.cs
- EntityWithChangeTrackerStrategy.cs
- DataGridColumnHeadersPresenterAutomationPeer.cs
- CompensatableTransactionScopeActivityDesigner.cs
- DataObject.cs
- SpecialFolderEnumConverter.cs
- Literal.cs
- Config.cs
- MarkupProperty.cs
- GC.cs
- PartialArray.cs
- SqlClientPermission.cs
- XmlNodeList.cs
- HebrewCalendar.cs
- InfoCardClaimCollection.cs
- DoubleSumAggregationOperator.cs
- DrawingServices.cs
- RequestCachePolicyConverter.cs
- Debugger.cs
- IncrementalCompileAnalyzer.cs
- WebPartsPersonalization.cs
- ScriptingWebServicesSectionGroup.cs
- HandlerBase.cs
- BindingParameterCollection.cs
- cookie.cs
- WebBrowserPermission.cs
- WebPartDeleteVerb.cs
- IsolationInterop.cs
- JsonDeserializer.cs
- NotifyIcon.cs
- Socket.cs
- SqlException.cs
- TextBoxLine.cs
- WebResourceAttribute.cs
- QueryableDataSource.cs
- SqlFlattener.cs
- SectionRecord.cs
- WebUtil.cs
- TemplateModeChangedEventArgs.cs
- FlowLayout.cs
- SourceChangedEventArgs.cs
- CharacterMetrics.cs
- OrderedDictionaryStateHelper.cs
- ActivityExecutorOperation.cs
- DocumentAutomationPeer.cs
- HostProtectionPermission.cs
- HitTestParameters.cs
- BezierSegment.cs
- TiffBitmapDecoder.cs
- RequiredFieldValidator.cs
- DataControlImageButton.cs
- EncodingFallbackAwareXmlTextWriter.cs
- Registry.cs
- RegexTypeEditor.cs
- DeferredElementTreeState.cs
- WorkflowServiceHost.cs
- ReadOnlyNameValueCollection.cs
- PixelShader.cs
- InfiniteIntConverter.cs
- DiscreteKeyFrames.cs
- TreeViewImageIndexConverter.cs
- SqlDataRecord.cs
- XmlSchemaSimpleTypeRestriction.cs
- codemethodreferenceexpression.cs
- IsolatedStorageFile.cs
- xml.cs
- UserControl.cs
- CheckPair.cs
- ReadOnlyPropertyMetadata.cs
- TextDocumentView.cs
- SelectedDatesCollection.cs
- CodeParameterDeclarationExpressionCollection.cs
- COM2ColorConverter.cs
- TextBoxAutoCompleteSourceConverter.cs
- XmlElement.cs
- EntityProviderServices.cs
- WebPartMinimizeVerb.cs
- FormatterServices.cs
- RegisteredExpandoAttribute.cs
- RSACryptoServiceProvider.cs