Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / 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();
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ForeignKeyConstraint.cs
- PathSegmentCollection.cs
- DbProviderConfigurationHandler.cs
- X509CertificateTrustedIssuerElement.cs
- DataGridCommandEventArgs.cs
- AvTraceDetails.cs
- Nullable.cs
- SupportsPreviewControlAttribute.cs
- StringPropertyBuilder.cs
- CodeTypeDeclaration.cs
- HttpClientCertificate.cs
- HttpResponse.cs
- NameValueSectionHandler.cs
- TouchEventArgs.cs
- ListViewUpdateEventArgs.cs
- ExpressionPrefixAttribute.cs
- CompilationUnit.cs
- RowToParametersTransformer.cs
- WebConfigurationManager.cs
- ConfigXmlDocument.cs
- ClientTargetCollection.cs
- ItemCheckEvent.cs
- SizeFConverter.cs
- SByte.cs
- XmlHierarchyData.cs
- ObjRef.cs
- SamlSubject.cs
- HasCopySemanticsAttribute.cs
- QualificationDataItem.cs
- ProcessModelInfo.cs
- SmtpFailedRecipientsException.cs
- NavigateUrlConverter.cs
- XmlSchemaAttribute.cs
- Context.cs
- ClaimTypes.cs
- FocusChangedEventArgs.cs
- LocalizableAttribute.cs
- SortQueryOperator.cs
- SchemaHelper.cs
- FastPropertyAccessor.cs
- InputProcessorProfilesLoader.cs
- HtmlImage.cs
- OperationPickerDialog.cs
- InputScope.cs
- OutOfMemoryException.cs
- DefaultWorkflowTransactionService.cs
- SqlDataSourceQueryConverter.cs
- EventLogPermissionEntryCollection.cs
- DynamicILGenerator.cs
- ProcessRequestArgs.cs
- InvalidAsynchronousStateException.cs
- CatalogZoneBase.cs
- GridToolTip.cs
- OutputScopeManager.cs
- ResponseBodyWriter.cs
- UnknownBitmapDecoder.cs
- ConstraintConverter.cs
- RoleService.cs
- FixedPageProcessor.cs
- DelegateSerializationHolder.cs
- ZoneButton.cs
- WebPartConnectionsCloseVerb.cs
- ExtendedPropertyCollection.cs
- SR.cs
- BlurBitmapEffect.cs
- PartialArray.cs
- XmlQueryCardinality.cs
- FontFamilyValueSerializer.cs
- XmlChildNodes.cs
- TableLayoutStyle.cs
- ItemsControlAutomationPeer.cs
- BaseCodeDomTreeGenerator.cs
- HttpCacheParams.cs
- HttpApplicationFactory.cs
- XmlAttribute.cs
- DummyDataSource.cs
- SerializationException.cs
- ExpressionBindingCollection.cs
- SamlAuthorizationDecisionStatement.cs
- ContainerSelectorActiveEvent.cs
- BrushConverter.cs
- DesignerAttribute.cs
- ZipIOModeEnforcingStream.cs
- CopyNamespacesAction.cs
- ProfileModule.cs
- CultureTable.cs
- DtdParser.cs
- DetailsViewDeleteEventArgs.cs
- OdbcErrorCollection.cs
- TraceSection.cs
- SqlConnectionManager.cs
- VarRefManager.cs
- GestureRecognizer.cs
- DbProviderFactories.cs
- ClipboardProcessor.cs
- HwndSource.cs
- ReadWriteObjectLock.cs
- Util.cs
- TableCellAutomationPeer.cs
- UseLicense.cs