CounterSet.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Diagnostics / PerformanceData / CounterSet.cs / 1407647 / CounterSet.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Diagnostics.PerformanceData { 
    using System; 
    using System.Threading;
    using System.Runtime.InteropServices; 
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis; 
    using System.Security.Permissions;
    using System.Security; 
    using Microsoft.Win32; 

    ///  
    /// CounterSet is equivalent to "Counter Object" in native performance counter terminology,
    /// or "Counter Category" in previous framework releases. It defines a abstract grouping of
    /// counters, where each counter defines measurable matrix. In the new performance counter
    /// infrastructure, CounterSet is defined by GUID called CounterSetGuid, and is hosted inside 
    /// provider application, which is also defined by another GUID called ProviderGuid.
    ///  
    [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] 
    public class CounterSet : IDisposable {
        private  static readonly bool           s_platformNotSupported = (Environment.OSVersion.Version.Major < 6); 
        internal PerfProvider                   m_provider;
        internal Guid                           m_providerGuid;
        internal Guid                           m_counterSet;
        internal CounterSetInstanceType         m_instType; 
        private  readonly Object                m_lockObject;
        private  bool                           m_instanceCreated; 
        internal Dictionary      m_stringToId; 
        internal Dictionary m_idToCounter;
 
        /// 
        /// CounterSet constructor.
        /// 
        /// ProviderGuid identifies the provider application. A provider identified by ProviderGuid could publish several CounterSets defined by different CounterSetGuids 
        /// CounterSetGuid identifies the specific CounterSet. CounterSetGuid should be unique.
        /// One of defined CounterSetInstanceType values 
        //  
        // 
        //  
        [System.Security.SecurityCritical]
        [PermissionSet(SecurityAction.Demand, Unrestricted = true)]
        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "guid", Justification = "Approved")]
        public CounterSet(Guid providerGuid, Guid counterSetGuid, CounterSetInstanceType instanceType) { 
            // Check only the mayor version, only support Windows Vista and later.
            // 
            if (s_platformNotSupported) { 
                throw new System.PlatformNotSupportedException(SR.GetString(SR.Perflib_PlatformNotSupported));
            } 
            if (! PerfProviderCollection.ValidateCounterSetInstanceType(instanceType)) {
                throw new ArgumentException(SR.GetString(SR.Perflib_Argument_InvalidCounterSetInstanceType, instanceType), "instanceType");
            }
 
            m_providerGuid = providerGuid;
            m_counterSet   = counterSetGuid; 
            m_instType     = instanceType; 
            PerfProviderCollection.RegisterCounterSet(m_counterSet);
            m_provider     = PerfProviderCollection.QueryProvider(m_providerGuid); 
            m_lockObject   = new Object();
            m_stringToId   = new Dictionary();
            m_idToCounter  = new Dictionary();
        } 

        public void Dispose() { 
            Dispose(true); 
            GC.SuppressFinalize(this);
        } 
        ~CounterSet() {
            Dispose(false);
        }
        //  
        // 
        //  
        [System.Security.SecuritySafeCritical] 
        protected virtual void Dispose(bool disposing) {
            lock(this) { 
                PerfProviderCollection.UnregisterCounterSet(m_counterSet);
                if (m_instanceCreated) {
                    if (m_provider != null) {
                        lock (m_lockObject) { 
                            if (m_provider != null) {
                                Interlocked.Decrement(ref m_provider.m_counterSet); 
                                if (m_provider.m_counterSet <= 0) { 
                                    PerfProviderCollection.RemoveProvider(m_providerGuid);
                                } 
                                m_provider = null;
                            }
                        }
                    } 
                }
            } 
        } 

        ///  
        /// Add non-displayable new counter to CounterSet; that is, perfmon would not display the counter.
        /// 
        /// CounterId uniquely identifies the counter within CounterSet
        /// One of defined CounterType values 
        [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
        public void AddCounter(Int32 counterId, CounterType counterType) { 
            if (m_provider == null) { 
                throw new InvalidOperationException(SR.GetString(SR.Perflib_InvalidOperation_NoActiveProvider, m_providerGuid));
            } 
            if (! PerfProviderCollection.ValidateCounterType(counterType)) {
                throw new ArgumentException(SR.GetString(SR.Perflib_Argument_InvalidCounterType, counterType), "counterType");
            }
            if (m_instanceCreated) { 
                throw new InvalidOperationException(SR.GetString(SR.Perflib_InvalidOperation_AddCounterAfterInstance, m_counterSet));
            } 
 
            lock (m_lockObject) {
                if (m_instanceCreated) { 
                    throw new InvalidOperationException(SR.GetString(SR.Perflib_InvalidOperation_AddCounterAfterInstance, m_counterSet));
                }
                if (m_idToCounter.ContainsKey(counterId)) {
                    throw new ArgumentException(SR.GetString(SR.Perflib_Argument_CounterAlreadyExists, counterId, m_counterSet), "CounterId"); 
                }
 
                m_idToCounter.Add(counterId, counterType); 
            }
        } 

        /// 
        /// Add named new counter to CounterSet.
        ///  
        /// CounterId uniquely identifies the counter within CounterSet
        /// One of defined CounterType values 
        /// This is friendly name to help provider developers as indexer. and it might not match what is displayed in counter consumption applications lie perfmon. 
        [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
        public void AddCounter(Int32 counterId, CounterType counterType, String counterName) { 
            if (counterName == null) {
                throw new ArgumentNullException("CounterName");
            }
            if (counterName.Length == 0) { 
                throw new ArgumentException(SR.GetString(SR.Perflib_Argument_EmptyCounterName), "counterName");
            } 
            if (! PerfProviderCollection.ValidateCounterType(counterType)) { 
                throw new ArgumentException(SR.GetString(SR.Perflib_Argument_InvalidCounterType, counterType), "counterType");
            } 
            if (m_provider == null) {
                throw new InvalidOperationException(SR.GetString(SR.Perflib_InvalidOperation_NoActiveProvider, m_providerGuid));
            }
            if (m_instanceCreated) { 
                throw new InvalidOperationException(SR.GetString(SR.Perflib_InvalidOperation_AddCounterAfterInstance, m_counterSet));
            } 
 
            lock (m_lockObject) {
                if (m_instanceCreated) { 
                    throw new InvalidOperationException(SR.GetString(SR.Perflib_InvalidOperation_AddCounterAfterInstance, m_counterSet));
                }
                if (m_stringToId.ContainsKey(counterName)) {
                    throw new ArgumentException(SR.GetString(SR.Perflib_Argument_CounterNameAlreadyExists, counterName, m_counterSet), "CounterName"); 
                }
                if (m_idToCounter.ContainsKey(counterId)) { 
                    throw new ArgumentException(SR.GetString(SR.Perflib_Argument_CounterAlreadyExists, counterId, m_counterSet), "CounterId"); 
                }
 
                m_stringToId.Add(counterName, counterId);
                m_idToCounter.Add(counterId, counterType);
            }
        } 

        ///  
        /// Create instances of the CounterSet. Created CounterSetInstance identifies active identity and tracks raw counter data for that identity. 
        /// 
        /// Friendly name identifies the instance. InstanceName would be shown in counter consumption applications like perfmon. 
        /// CounterSetInstance object
        // 
        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        [System.Security.SecurityCritical]
        [PermissionSet(SecurityAction.Demand, Unrestricted = true)] 
        [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
        public CounterSetInstance CreateCounterSetInstance(String instanceName) { 
            if (instanceName == null) { 
                throw new ArgumentNullException("instanceName");
            } 
            if (instanceName.Length == 0) {
                throw new ArgumentException(SR.GetString(SR.Perflib_Argument_EmptyInstanceName), "instanceName");
            }
            if (m_provider == null) { 
                throw new InvalidOperationException(SR.GetString(SR.Perflib_InvalidOperation_NoActiveProvider, m_providerGuid));
            } 
            if (! m_instanceCreated) { 
                lock (m_lockObject) {
                    if (! m_instanceCreated) { 
                        if (m_provider == null) {
                            throw new ArgumentException(SR.GetString(SR.Perflib_Argument_ProviderNotFound, m_providerGuid), "ProviderGuid");
                        }
                        if (m_provider.m_hProvider.IsInvalid) { 
                            throw new InvalidOperationException(SR.GetString(SR.Perflib_InvalidOperation_NoActiveProvider, m_providerGuid));
                        } 
                        if (m_idToCounter.Count == 0) { 
                            throw new InvalidOperationException(SR.GetString(SR.Perflib_InvalidOperation_CounterSetContainsNoCounter, m_counterSet));
                        } 

                        uint Status = (uint) UnsafeNativeMethods.ERROR_SUCCESS;

                        unsafe { 
                            uint CounterSetInfoSize   = (uint) sizeof(UnsafeNativeMethods.PerfCounterSetInfoStruct)
                                            + (uint) m_idToCounter.Count * (uint) sizeof(UnsafeNativeMethods.PerfCounterInfoStruct); 
                            uint   CounterSetInfoUsed = 0; 
                            byte * CounterSetBuffer   = stackalloc byte[(int)CounterSetInfoSize];
 
                            if (CounterSetBuffer == null) {
                                throw new InsufficientMemoryException(SR.GetString(SR.Perflib_InsufficientMemory_CounterSetTemplate, m_counterSet, CounterSetInfoSize));
                            }
 
                            UnsafeNativeMethods.PerfCounterSetInfoStruct * CounterSetInfo;
                            UnsafeNativeMethods.PerfCounterInfoStruct    * CounterInfo; 
 
                            uint CurrentCounter = 0;
                            uint CurrentOffset  = 0; 

                            CounterSetInfo = (UnsafeNativeMethods.PerfCounterSetInfoStruct *) CounterSetBuffer;
                            CounterSetInfo->CounterSetGuid = m_counterSet;
                            CounterSetInfo->ProviderGuid   = m_providerGuid; 
                            CounterSetInfo->NumCounters    = (uint) m_idToCounter.Count;
                            CounterSetInfo->InstanceType   = (uint) m_instType; 
 
                            foreach (KeyValuePair CounterDef in m_idToCounter) {
                                CounterSetInfoUsed = (uint)sizeof(UnsafeNativeMethods.PerfCounterSetInfoStruct) 
                                                + (uint)CurrentCounter * (uint)sizeof(UnsafeNativeMethods.PerfCounterInfoStruct);
                                if (CounterSetInfoUsed < CounterSetInfoSize) {
                                    CounterInfo = (UnsafeNativeMethods.PerfCounterInfoStruct *) (CounterSetBuffer + CounterSetInfoUsed);
                                    CounterInfo->CounterId   = (uint) CounterDef.Key; 
                                    CounterInfo->CounterType = (uint) CounterDef.Value;
                                    CounterInfo->Attrib      = 0x0000000000000001;   // PERF_ATTRIB_BY_REFERENCE 
                                    CounterInfo->Size        = (uint) sizeof(void*); // always use pointer size 
                                    CounterInfo->DetailLevel = 100;                  // PERF_DETAIL_NOVICE
                                    CounterInfo->Scale       = 0;                    // Default scale 
                                    CounterInfo->Offset      = CurrentOffset;

                                    CurrentOffset += CounterInfo->Size;
                                } 
                                CurrentCounter++;
                            } 
                            Status = UnsafeNativeMethods.PerfSetCounterSetInfo(m_provider.m_hProvider, CounterSetInfo, CounterSetInfoSize); 
                            // ERROR_INVALID_PARAMETER, ERROR_ALREADY_EXISTS, ERROR_NOT_ENOUGH_MEMORY, ERROR_OUTOFMEMORY
                            if (Status != (uint) UnsafeNativeMethods.ERROR_SUCCESS) { 
                                switch (Status) {
                                    case (uint) UnsafeNativeMethods.ERROR_ALREADY_EXISTS:
                                        throw new ArgumentException(SR.GetString(SR.Perflib_Argument_CounterSetAlreadyRegister, m_counterSet), "CounterSetGuid");
 
                                    default:
                                        throw new Win32Exception((int) Status); 
                                } 
                            }
 
                            Interlocked.Increment(ref m_provider.m_counterSet);
                        }

                        m_instanceCreated = true; 
                    }
                } 
            } 

            CounterSetInstance thisInst = new CounterSetInstance(this, instanceName); 
            return thisInst;
        }
    }
} 


// 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