_LocalDataStoreMgr.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / _LocalDataStoreMgr.cs / 1305376 / _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.Generic; 
    using System.Threading;
    using System.Runtime.CompilerServices;
    using System.Diagnostics.Contracts;
 
    // 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 LocalDataStoreMgr m_mgr;
        private int m_slot; 
        private long m_cookie;
 
        // Construct the object to encapsulate the slot. 
        internal LocalDataStoreSlot(LocalDataStoreMgr mgr, int slot, long cookie)
        { 
            m_mgr = mgr;
            m_slot = slot;
            m_cookie = cookie;
        } 

        // Accessors for the two fields of this class. 
        internal LocalDataStoreMgr Manager 
        {
            get 
            {
                return m_mgr;
            }
        } 
        internal int Slot
        { 
            get 
            {
                return m_slot; 
            }
        }
        internal long Cookie
        { 
            get
            { 
                return m_cookie; 
        }
        } 

        // Release the slot reserved by this object when this object goes away.
        ~LocalDataStoreSlot()
        { 
            LocalDataStoreMgr mgr = m_mgr;
            if (mgr == null) 
                return; 

            int slot = m_slot; 

                // Mark the slot as free.
                m_slot = -1;
 
            mgr.FreeDataSlot(slot, m_cookie);
        } 
    } 

    // This class will not be marked serializable 
    sealed internal class LocalDataStoreMgr
    {
        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.
        =========================================================================*/
        [System.Security.SecuritySafeCritical]  // auto-generated
        public LocalDataStoreHolder CreateLocalDataStore() 
        {
            // Create a new local data store. 
            LocalDataStore store = new LocalDataStore(this, m_SlotInfoTable.Length); 
            LocalDataStoreHolder holder = new LocalDataStoreHolder(store);
 
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            { 
                Monitor.Enter(this, ref tookLock);
                // Add the store to the array list and return it. 
                m_ManagedLocalDataStores.Add(store); 
            }
            finally 
            {
                if (tookLock)
                    Monitor.Exit(this);
            } 
            return holder;
        } 
 
        /*=========================================================================
         * Remove the specified store from the list of managed stores.. 
        =========================================================================*/
        [System.Security.SecuritySafeCritical]  // auto-generated
        public void DeleteLocalDataStore(LocalDataStore store)
        { 
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try 
            {
                Monitor.Enter(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.
        =========================================================================*/ 
        [System.Security.SecuritySafeCritical]  // auto-generated 
        public LocalDataStoreSlot AllocateDataSlot()
        { 
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            { 
                Monitor.Enter(this, ref tookLock);
                LocalDataStoreSlot slot; 
 
                // Check if there are any slots left.
                int SlotTableSize = m_SlotInfoTable.Length; 
                if (m_FirstAvailableSlot >= SlotTableSize)
                {
                    // 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. 
                    bool[] NewSlotInfoTable = new bool[NewSlotTableSize];
 
                    // Copy the old array into the new one.
                    Array.Copy(m_SlotInfoTable, NewSlotInfoTable, SlotTableSize);
                    m_SlotInfoTable = NewSlotInfoTable;
 
                    m_FirstAvailableSlot = SlotTableSize;
 
                    SlotTableSize = NewSlotTableSize; 
                }
 
                // Find the first actually available slot.
                int availableSlot = m_FirstAvailableSlot;
                for (; ; )
                { 
                    if (!m_SlotInfoTable[availableSlot])
                        break; 
                    availableSlot++; 
                }
                m_SlotInfoTable[availableSlot] = true; 

                // availableSlot is the index of the empty slot.
                //
                // We do not need to worry about overflowing m_CookieGenerator. It would take centuries 
                // of intensive slot allocations on current machines to get the 2^64 counter to overflow.
                // We will perform the increment with overflow check just to play it on the safe side. 
                slot = new LocalDataStoreSlot(this, availableSlot, checked(m_CookieGenerator++)); 

                // Save the new "first available slot".hint 
                // In case FreeDataSlot has moved the pointer back, the next slot may not be available.
                availableSlot ++;
                while (availableSlot < SlotTableSize)
                { 
                    if (m_SlotInfoTable[availableSlot])
                    { 
                        break; 
                    }
                    availableSlot ++; 
                }
                m_FirstAvailableSlot = availableSlot;

                // Return the selected slot 
                return slot;
            } 
            finally 
            {
                if (tookLock) 
                    Monitor.Exit(this);
            }
        }
 
        /*==========================================================================
        ** Allocate a slot and associate a name with it. 
        =========================================================================*/ 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public LocalDataStoreSlot AllocateNamedDataSlot(String name) 
        {
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
                Monitor.Enter(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. 
        =========================================================================*/ 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public LocalDataStoreSlot GetNamedDataSlot(String name) 
        {
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
                Monitor.Enter(this, ref tookLock); 
                // Lookup in the hashtable to try find a slot for the name. 
                LocalDataStoreSlot slot = m_KeyToSlotMap.GetValueOrDefault(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.
        =========================================================================*/ 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public void FreeNamedDataSlot(String name)
        {
            bool tookLock = false; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            { 
                Monitor.Enter(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.
        =========================================================================*/
        [System.Security.SecuritySafeCritical]  // auto-generated 
        internal void FreeDataSlot(int slot, long cookie)
        { 
            bool tookLock = false; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
                Monitor.Enter(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]).FreeData(slot, cookie); 
                } 

                // Mark the slot as being no longer occupied. 
                m_SlotInfoTable[slot] = false;
                if (slot < m_FirstAvailableSlot)
                    m_FirstAvailableSlot = slot;
            } 
            finally
            { 
                if (tookLock) 
                    Monitor.Exit(this);
            } 
        }

        /*=========================================================================
        ** Check that this is a valid slot for this store 
        =========================================================================*/
        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"));
            Contract.EndContractBlock();
        }
 
        /*==========================================================================
        ** Return the number of allocated slots in this manager. 
        =========================================================================*/ 
        internal int GetSlotTableLength()
        { 
            return m_SlotInfoTable.Length;
        }

        private bool[] m_SlotInfoTable = new bool[InitialSlotTableSize]; 
        private int m_FirstAvailableSlot;
        private List m_ManagedLocalDataStores = new List(); 
        private Dictionary m_KeyToSlotMap = new Dictionary(); 
        private long m_CookieGenerator;
    } 
}

// 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.Generic; 
    using System.Threading;
    using System.Runtime.CompilerServices;
    using System.Diagnostics.Contracts;
 
    // 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 LocalDataStoreMgr m_mgr;
        private int m_slot; 
        private long m_cookie;
 
        // Construct the object to encapsulate the slot. 
        internal LocalDataStoreSlot(LocalDataStoreMgr mgr, int slot, long cookie)
        { 
            m_mgr = mgr;
            m_slot = slot;
            m_cookie = cookie;
        } 

        // Accessors for the two fields of this class. 
        internal LocalDataStoreMgr Manager 
        {
            get 
            {
                return m_mgr;
            }
        } 
        internal int Slot
        { 
            get 
            {
                return m_slot; 
            }
        }
        internal long Cookie
        { 
            get
            { 
                return m_cookie; 
        }
        } 

        // Release the slot reserved by this object when this object goes away.
        ~LocalDataStoreSlot()
        { 
            LocalDataStoreMgr mgr = m_mgr;
            if (mgr == null) 
                return; 

            int slot = m_slot; 

                // Mark the slot as free.
                m_slot = -1;
 
            mgr.FreeDataSlot(slot, m_cookie);
        } 
    } 

    // This class will not be marked serializable 
    sealed internal class LocalDataStoreMgr
    {
        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.
        =========================================================================*/
        [System.Security.SecuritySafeCritical]  // auto-generated
        public LocalDataStoreHolder CreateLocalDataStore() 
        {
            // Create a new local data store. 
            LocalDataStore store = new LocalDataStore(this, m_SlotInfoTable.Length); 
            LocalDataStoreHolder holder = new LocalDataStoreHolder(store);
 
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            { 
                Monitor.Enter(this, ref tookLock);
                // Add the store to the array list and return it. 
                m_ManagedLocalDataStores.Add(store); 
            }
            finally 
            {
                if (tookLock)
                    Monitor.Exit(this);
            } 
            return holder;
        } 
 
        /*=========================================================================
         * Remove the specified store from the list of managed stores.. 
        =========================================================================*/
        [System.Security.SecuritySafeCritical]  // auto-generated
        public void DeleteLocalDataStore(LocalDataStore store)
        { 
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try 
            {
                Monitor.Enter(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.
        =========================================================================*/ 
        [System.Security.SecuritySafeCritical]  // auto-generated 
        public LocalDataStoreSlot AllocateDataSlot()
        { 
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            { 
                Monitor.Enter(this, ref tookLock);
                LocalDataStoreSlot slot; 
 
                // Check if there are any slots left.
                int SlotTableSize = m_SlotInfoTable.Length; 
                if (m_FirstAvailableSlot >= SlotTableSize)
                {
                    // 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. 
                    bool[] NewSlotInfoTable = new bool[NewSlotTableSize];
 
                    // Copy the old array into the new one.
                    Array.Copy(m_SlotInfoTable, NewSlotInfoTable, SlotTableSize);
                    m_SlotInfoTable = NewSlotInfoTable;
 
                    m_FirstAvailableSlot = SlotTableSize;
 
                    SlotTableSize = NewSlotTableSize; 
                }
 
                // Find the first actually available slot.
                int availableSlot = m_FirstAvailableSlot;
                for (; ; )
                { 
                    if (!m_SlotInfoTable[availableSlot])
                        break; 
                    availableSlot++; 
                }
                m_SlotInfoTable[availableSlot] = true; 

                // availableSlot is the index of the empty slot.
                //
                // We do not need to worry about overflowing m_CookieGenerator. It would take centuries 
                // of intensive slot allocations on current machines to get the 2^64 counter to overflow.
                // We will perform the increment with overflow check just to play it on the safe side. 
                slot = new LocalDataStoreSlot(this, availableSlot, checked(m_CookieGenerator++)); 

                // Save the new "first available slot".hint 
                // In case FreeDataSlot has moved the pointer back, the next slot may not be available.
                availableSlot ++;
                while (availableSlot < SlotTableSize)
                { 
                    if (m_SlotInfoTable[availableSlot])
                    { 
                        break; 
                    }
                    availableSlot ++; 
                }
                m_FirstAvailableSlot = availableSlot;

                // Return the selected slot 
                return slot;
            } 
            finally 
            {
                if (tookLock) 
                    Monitor.Exit(this);
            }
        }
 
        /*==========================================================================
        ** Allocate a slot and associate a name with it. 
        =========================================================================*/ 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public LocalDataStoreSlot AllocateNamedDataSlot(String name) 
        {
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
                Monitor.Enter(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. 
        =========================================================================*/ 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public LocalDataStoreSlot GetNamedDataSlot(String name) 
        {
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
                Monitor.Enter(this, ref tookLock); 
                // Lookup in the hashtable to try find a slot for the name. 
                LocalDataStoreSlot slot = m_KeyToSlotMap.GetValueOrDefault(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.
        =========================================================================*/ 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public void FreeNamedDataSlot(String name)
        {
            bool tookLock = false; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            { 
                Monitor.Enter(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.
        =========================================================================*/
        [System.Security.SecuritySafeCritical]  // auto-generated 
        internal void FreeDataSlot(int slot, long cookie)
        { 
            bool tookLock = false; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
                Monitor.Enter(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]).FreeData(slot, cookie); 
                } 

                // Mark the slot as being no longer occupied. 
                m_SlotInfoTable[slot] = false;
                if (slot < m_FirstAvailableSlot)
                    m_FirstAvailableSlot = slot;
            } 
            finally
            { 
                if (tookLock) 
                    Monitor.Exit(this);
            } 
        }

        /*=========================================================================
        ** Check that this is a valid slot for this store 
        =========================================================================*/
        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"));
            Contract.EndContractBlock();
        }
 
        /*==========================================================================
        ** Return the number of allocated slots in this manager. 
        =========================================================================*/ 
        internal int GetSlotTableLength()
        { 
            return m_SlotInfoTable.Length;
        }

        private bool[] m_SlotInfoTable = new bool[InitialSlotTableSize]; 
        private int m_FirstAvailableSlot;
        private List m_ManagedLocalDataStores = new List(); 
        private Dictionary m_KeyToSlotMap = new Dictionary(); 
        private long m_CookieGenerator;
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK