Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / clr / src / BCL / System / _LocalDataStoreMgr.cs / 1 / _LocalDataStoreMgr.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*==============================================================================
**
** Class: LocalDataStoreMgr
**
**
** Purpose: Class that manages stores of local data. This class is used in
** cooperation with the LocalDataStore class.
**
**
=============================================================================*/
namespace System {
using System;
using System.Collections;
using System.Threading;
using System.Runtime.CompilerServices;
// This is a cheesy internal helper class that is used to make sure memory
// is actually being accessed and not some cached copy of a field in a
// register.
// WARNING: If we every do type analysis to eliminate virtual functions,
// this will break.
// This class will not be marked serializable
internal class LdsSyncHelper
{
internal virtual int Get(ref int slot)
{
return slot;
}
}
// This class is an encapsulation of a slot so that it is managed in a secure fashion.
// It is constructed by the LocalDataStoreManager, holds the slot and the manager
// and cleans up when it is finalized.
// This class will not be marked serializable
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class LocalDataStoreSlot
{
private static LdsSyncHelper m_helper = new LdsSyncHelper();
private LocalDataStoreMgr m_mgr;
private int m_slot;
// Construct the object to encapsulate the slot.
internal LocalDataStoreSlot(LocalDataStoreMgr mgr, int slot)
{
m_mgr = mgr;
m_slot = slot;
}
// Accessors for the two fields of this class.
internal LocalDataStoreMgr Manager
{
get
{
return m_mgr;
}
}
internal int Slot
{
get
{
return m_slot;
}
}
// This is used to make sure we are actually reading and writing to
// memory to fetch the slot (rather than possibly using a value
// cached in a register).
internal bool IsValid()
{
return m_helper.Get(ref m_slot) != -1;
}
// Release the slot reserved by this object when this object goes away.
// There is a race condition that can happen in the face of
// resurrection where another thread is fetching values or assigning
// while the finalizer thread is here. We are counting on the fact
// that code that fetches values calls IsValid after fetching a value
// and before giving it to anyone. See LocalDataStore for the other
// half of this. We are also counting on code that sets values locks
// the manager.
~LocalDataStoreSlot()
{
int slot = m_slot;
// This lock fixes synchronization with the assignment of values.
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(m_mgr, ref tookLock);
// Mark the slot as free.
m_slot = -1;
m_mgr.FreeDataSlot(slot);
}
finally {
if (tookLock)
Monitor.Exit(m_mgr);
}
}
}
// This class will not be marked serializable
internal class LocalDataStoreMgr
{
private const byte DataSlotOccupied = 0x01;
private const int InitialSlotTableSize = 64;
private const int SlotTableDoubleThreshold = 512;
private const int LargeSlotTableSizeIncrease = 128;
/*=========================================================================
** Create a data store to be managed by this manager and add it to the
** list. The initial size of the new store matches the number of slots
** allocated in this manager.
=========================================================================*/
public LocalDataStore CreateLocalDataStore()
{
// Create a new local data store.
LocalDataStore Store = new LocalDataStore(this, m_SlotInfoTable.Length);
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Add the store to the array list and return it.
m_ManagedLocalDataStores.Add(Store);
}
finally {
if (tookLock)
Monitor.Exit(this);
}
return Store;
}
/*=========================================================================
* Remove the specified store from the list of managed stores..
=========================================================================*/
public void DeleteLocalDataStore(LocalDataStore store)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Remove the store to the array list and return it.
m_ManagedLocalDataStores.Remove(store);
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*=========================================================================
** Allocates a data slot by finding an available index and wrapping it
** an object to prevent clients from manipulating it directly, allowing us
** to make assumptions its integrity.
=========================================================================*/
public LocalDataStoreSlot AllocateDataSlot()
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
int i;
LocalDataStoreSlot slot;
// Retrieve the current size of the table.
int SlotTableSize = m_SlotInfoTable.Length;
// Check if there are any slots left.
if (m_FirstAvailableSlot < SlotTableSize)
{
// Save the first available slot.
slot = new LocalDataStoreSlot(this, m_FirstAvailableSlot);
m_SlotInfoTable[m_FirstAvailableSlot] = DataSlotOccupied;
// Find the next available slot.
for (i=m_FirstAvailableSlot+1; i < SlotTableSize; ++i)
if (0 == (m_SlotInfoTable[i] & DataSlotOccupied))
break;
// Save the new "first available slot".
m_FirstAvailableSlot = i;
// Return the slot index.
return slot;
}
// The table is full so we need to increase its size.
int NewSlotTableSize;
if (SlotTableSize < SlotTableDoubleThreshold)
{
// The table is still relatively small so double it.
NewSlotTableSize = SlotTableSize * 2;
}
else
{
// The table is relatively large so simply increase its size by a given amount.
NewSlotTableSize = SlotTableSize + LargeSlotTableSizeIncrease;
}
// Allocate the new slot info table.
byte[] NewSlotInfoTable = new byte[NewSlotTableSize];
// Copy the old array into the new one.
Array.Copy(m_SlotInfoTable, NewSlotInfoTable, SlotTableSize);
m_SlotInfoTable = NewSlotInfoTable;
// SlotTableSize is the index of the first empty slot in the expanded table.
slot = new LocalDataStoreSlot(this, SlotTableSize);
m_SlotInfoTable[SlotTableSize] = DataSlotOccupied;
m_FirstAvailableSlot = SlotTableSize + 1;
// Return the selected slot
return slot;
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*==========================================================================
** Allocate a slot and associate a name with it.
=========================================================================*/
public LocalDataStoreSlot AllocateNamedDataSlot(String name)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Allocate a normal data slot.
LocalDataStoreSlot slot = AllocateDataSlot();
// Insert the association between the name and the data slot number
// in the hash table.
m_KeyToSlotMap.Add(name, slot);
return slot;
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*=========================================================================
** Retrieve the slot associated with a name, allocating it if no such
** association has been defined.
=========================================================================*/
public LocalDataStoreSlot GetNamedDataSlot(String name)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Lookup in the hashtable to try find a slot for the name.
LocalDataStoreSlot slot = (LocalDataStoreSlot) m_KeyToSlotMap[name];
// If the name is not yet in the hashtable then add it.
if (null == slot)
return AllocateNamedDataSlot(name);
// The name was in the hashtable so return the associated slot.
return slot;
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*==========================================================================
** Eliminate the association of a name with a slot. The actual slot will
** be reclaimed when the finalizer for the slot object runs.
=========================================================================*/
public void FreeNamedDataSlot(String name)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Remove the name slot association from the hashtable.
m_KeyToSlotMap.Remove(name);
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*==========================================================================
** Free's a previously allocated data slot on ALL the managed data stores.
=========================================================================*/
internal void FreeDataSlot(int slot)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Go thru all the managed stores and set the data on the specified slot to 0.
for (int i=0; i < m_ManagedLocalDataStores.Count; i++)
{
((LocalDataStore)m_ManagedLocalDataStores[i]).SetDataInternal(
slot,
null,
false);
}
// Mark the slot as being no longer occupied.
m_SlotInfoTable[slot] = 0;
if (slot < m_FirstAvailableSlot)
m_FirstAvailableSlot = slot;
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*=========================================================================
** Return the number of allocated slots in this manager.
=========================================================================*/
public void ValidateSlot(LocalDataStoreSlot slot)
{
// Make sure the slot was allocated for this store.
if (slot==null || slot.Manager != this)
throw new ArgumentException(Environment.GetResourceString("Argument_ALSInvalidSlot"));
}
/*==========================================================================
** Return the number of allocated slots in this manager.
=========================================================================*/
internal int GetSlotTableLength()
{
return m_SlotInfoTable.Length;
}
private byte[] m_SlotInfoTable = new byte[InitialSlotTableSize];
private int m_FirstAvailableSlot = 0;
private ArrayList m_ManagedLocalDataStores = new ArrayList();
private Hashtable m_KeyToSlotMap = new Hashtable();
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*==============================================================================
**
** Class: LocalDataStoreMgr
**
**
** Purpose: Class that manages stores of local data. This class is used in
** cooperation with the LocalDataStore class.
**
**
=============================================================================*/
namespace System {
using System;
using System.Collections;
using System.Threading;
using System.Runtime.CompilerServices;
// This is a cheesy internal helper class that is used to make sure memory
// is actually being accessed and not some cached copy of a field in a
// register.
// WARNING: If we every do type analysis to eliminate virtual functions,
// this will break.
// This class will not be marked serializable
internal class LdsSyncHelper
{
internal virtual int Get(ref int slot)
{
return slot;
}
}
// This class is an encapsulation of a slot so that it is managed in a secure fashion.
// It is constructed by the LocalDataStoreManager, holds the slot and the manager
// and cleans up when it is finalized.
// This class will not be marked serializable
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class LocalDataStoreSlot
{
private static LdsSyncHelper m_helper = new LdsSyncHelper();
private LocalDataStoreMgr m_mgr;
private int m_slot;
// Construct the object to encapsulate the slot.
internal LocalDataStoreSlot(LocalDataStoreMgr mgr, int slot)
{
m_mgr = mgr;
m_slot = slot;
}
// Accessors for the two fields of this class.
internal LocalDataStoreMgr Manager
{
get
{
return m_mgr;
}
}
internal int Slot
{
get
{
return m_slot;
}
}
// This is used to make sure we are actually reading and writing to
// memory to fetch the slot (rather than possibly using a value
// cached in a register).
internal bool IsValid()
{
return m_helper.Get(ref m_slot) != -1;
}
// Release the slot reserved by this object when this object goes away.
// There is a race condition that can happen in the face of
// resurrection where another thread is fetching values or assigning
// while the finalizer thread is here. We are counting on the fact
// that code that fetches values calls IsValid after fetching a value
// and before giving it to anyone. See LocalDataStore for the other
// half of this. We are also counting on code that sets values locks
// the manager.
~LocalDataStoreSlot()
{
int slot = m_slot;
// This lock fixes synchronization with the assignment of values.
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(m_mgr, ref tookLock);
// Mark the slot as free.
m_slot = -1;
m_mgr.FreeDataSlot(slot);
}
finally {
if (tookLock)
Monitor.Exit(m_mgr);
}
}
}
// This class will not be marked serializable
internal class LocalDataStoreMgr
{
private const byte DataSlotOccupied = 0x01;
private const int InitialSlotTableSize = 64;
private const int SlotTableDoubleThreshold = 512;
private const int LargeSlotTableSizeIncrease = 128;
/*=========================================================================
** Create a data store to be managed by this manager and add it to the
** list. The initial size of the new store matches the number of slots
** allocated in this manager.
=========================================================================*/
public LocalDataStore CreateLocalDataStore()
{
// Create a new local data store.
LocalDataStore Store = new LocalDataStore(this, m_SlotInfoTable.Length);
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Add the store to the array list and return it.
m_ManagedLocalDataStores.Add(Store);
}
finally {
if (tookLock)
Monitor.Exit(this);
}
return Store;
}
/*=========================================================================
* Remove the specified store from the list of managed stores..
=========================================================================*/
public void DeleteLocalDataStore(LocalDataStore store)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Remove the store to the array list and return it.
m_ManagedLocalDataStores.Remove(store);
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*=========================================================================
** Allocates a data slot by finding an available index and wrapping it
** an object to prevent clients from manipulating it directly, allowing us
** to make assumptions its integrity.
=========================================================================*/
public LocalDataStoreSlot AllocateDataSlot()
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
int i;
LocalDataStoreSlot slot;
// Retrieve the current size of the table.
int SlotTableSize = m_SlotInfoTable.Length;
// Check if there are any slots left.
if (m_FirstAvailableSlot < SlotTableSize)
{
// Save the first available slot.
slot = new LocalDataStoreSlot(this, m_FirstAvailableSlot);
m_SlotInfoTable[m_FirstAvailableSlot] = DataSlotOccupied;
// Find the next available slot.
for (i=m_FirstAvailableSlot+1; i < SlotTableSize; ++i)
if (0 == (m_SlotInfoTable[i] & DataSlotOccupied))
break;
// Save the new "first available slot".
m_FirstAvailableSlot = i;
// Return the slot index.
return slot;
}
// The table is full so we need to increase its size.
int NewSlotTableSize;
if (SlotTableSize < SlotTableDoubleThreshold)
{
// The table is still relatively small so double it.
NewSlotTableSize = SlotTableSize * 2;
}
else
{
// The table is relatively large so simply increase its size by a given amount.
NewSlotTableSize = SlotTableSize + LargeSlotTableSizeIncrease;
}
// Allocate the new slot info table.
byte[] NewSlotInfoTable = new byte[NewSlotTableSize];
// Copy the old array into the new one.
Array.Copy(m_SlotInfoTable, NewSlotInfoTable, SlotTableSize);
m_SlotInfoTable = NewSlotInfoTable;
// SlotTableSize is the index of the first empty slot in the expanded table.
slot = new LocalDataStoreSlot(this, SlotTableSize);
m_SlotInfoTable[SlotTableSize] = DataSlotOccupied;
m_FirstAvailableSlot = SlotTableSize + 1;
// Return the selected slot
return slot;
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*==========================================================================
** Allocate a slot and associate a name with it.
=========================================================================*/
public LocalDataStoreSlot AllocateNamedDataSlot(String name)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Allocate a normal data slot.
LocalDataStoreSlot slot = AllocateDataSlot();
// Insert the association between the name and the data slot number
// in the hash table.
m_KeyToSlotMap.Add(name, slot);
return slot;
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*=========================================================================
** Retrieve the slot associated with a name, allocating it if no such
** association has been defined.
=========================================================================*/
public LocalDataStoreSlot GetNamedDataSlot(String name)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Lookup in the hashtable to try find a slot for the name.
LocalDataStoreSlot slot = (LocalDataStoreSlot) m_KeyToSlotMap[name];
// If the name is not yet in the hashtable then add it.
if (null == slot)
return AllocateNamedDataSlot(name);
// The name was in the hashtable so return the associated slot.
return slot;
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*==========================================================================
** Eliminate the association of a name with a slot. The actual slot will
** be reclaimed when the finalizer for the slot object runs.
=========================================================================*/
public void FreeNamedDataSlot(String name)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Remove the name slot association from the hashtable.
m_KeyToSlotMap.Remove(name);
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*==========================================================================
** Free's a previously allocated data slot on ALL the managed data stores.
=========================================================================*/
internal void FreeDataSlot(int slot)
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
// Go thru all the managed stores and set the data on the specified slot to 0.
for (int i=0; i < m_ManagedLocalDataStores.Count; i++)
{
((LocalDataStore)m_ManagedLocalDataStores[i]).SetDataInternal(
slot,
null,
false);
}
// Mark the slot as being no longer occupied.
m_SlotInfoTable[slot] = 0;
if (slot < m_FirstAvailableSlot)
m_FirstAvailableSlot = slot;
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}
/*=========================================================================
** Return the number of allocated slots in this manager.
=========================================================================*/
public void ValidateSlot(LocalDataStoreSlot slot)
{
// Make sure the slot was allocated for this store.
if (slot==null || slot.Manager != this)
throw new ArgumentException(Environment.GetResourceString("Argument_ALSInvalidSlot"));
}
/*==========================================================================
** Return the number of allocated slots in this manager.
=========================================================================*/
internal int GetSlotTableLength()
{
return m_SlotInfoTable.Length;
}
private byte[] m_SlotInfoTable = new byte[InitialSlotTableSize];
private int m_FirstAvailableSlot = 0;
private ArrayList m_ManagedLocalDataStores = new ArrayList();
private Hashtable m_KeyToSlotMap = new Hashtable();
}
}
// 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
- ColorAnimation.cs
- XmlUtf8RawTextWriter.cs
- TemplateXamlParser.cs
- EncodingTable.cs
- KerberosRequestorSecurityToken.cs
- ScriptingProfileServiceSection.cs
- MachineKey.cs
- DbBuffer.cs
- Decimal.cs
- DataPagerField.cs
- DictionaryMarkupSerializer.cs
- SoapDocumentMethodAttribute.cs
- XmlObjectSerializerWriteContextComplex.cs
- TextAutomationPeer.cs
- BooleanStorage.cs
- TimeSpan.cs
- XmlQueryCardinality.cs
- WindowsListViewScroll.cs
- GeometryGroup.cs
- DropShadowEffect.cs
- DataFieldEditor.cs
- SqlXmlStorage.cs
- WebPartDisplayModeCancelEventArgs.cs
- CodeEventReferenceExpression.cs
- ServerValidateEventArgs.cs
- ServiceX509SecurityTokenProvider.cs
- ArithmeticLiteral.cs
- Process.cs
- Encoding.cs
- ConfigXmlDocument.cs
- ButtonBase.cs
- SecondaryIndex.cs
- sqlpipe.cs
- FunctionOverloadResolver.cs
- SafeLibraryHandle.cs
- OracleParameter.cs
- ResourceManagerWrapper.cs
- CompressedStack.cs
- DataSourceCacheDurationConverter.cs
- CodeNamespaceCollection.cs
- BinaryFormatterWriter.cs
- NullToBooleanConverter.cs
- Sequence.cs
- _Semaphore.cs
- ActionItem.cs
- HttpResponseHeader.cs
- HttpCacheVary.cs
- SiblingIterators.cs
- safemediahandle.cs
- Screen.cs
- PeerApplication.cs
- SchemaCompiler.cs
- securitycriticaldata.cs
- EmptyCollection.cs
- CalendarData.cs
- DropShadowBitmapEffect.cs
- DiagnosticTrace.cs
- ListControlDesigner.cs
- GlobalDataBindingHandler.cs
- LinkTarget.cs
- BitmapEncoder.cs
- TextClipboardData.cs
- AbstractDataSvcMapFileLoader.cs
- TypeConstant.cs
- IsolationInterop.cs
- XmlSerializableReader.cs
- EventSourceCreationData.cs
- PasswordTextContainer.cs
- _ListenerResponseStream.cs
- TextTreeRootTextBlock.cs
- HierarchicalDataBoundControlAdapter.cs
- UpdatePanelTriggerCollection.cs
- SqlWebEventProvider.cs
- OdbcConnectionFactory.cs
- DesignTableCollection.cs
- wgx_commands.cs
- DesignerView.Commands.cs
- ApplicationFileCodeDomTreeGenerator.cs
- FixedSOMPageElement.cs
- HtmlTableRow.cs
- wgx_commands.cs
- Vector3DValueSerializer.cs
- __ConsoleStream.cs
- WebEventTraceProvider.cs
- Trace.cs
- InternalUserCancelledException.cs
- SemanticTag.cs
- MultiSelector.cs
- Base64Encoder.cs
- XPathNavigator.cs
- GridViewColumnHeader.cs
- _ScatterGatherBuffers.cs
- FormsAuthenticationEventArgs.cs
- WebPartDisplayMode.cs
- DeploymentExceptionMapper.cs
- SessionSymmetricTransportSecurityProtocolFactory.cs
- Size.cs
- StaticDataManager.cs
- HandlerBase.cs
- DataKey.cs