|
//------------------------------------------------------------------------------
// <copyright file="PerfProviderCollection.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Diagnostics.PerformanceData {
using System;
using System.Threading;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Security;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
internal sealed class PerfProvider {
internal Guid m_providerGuid;
internal Int32 m_counterSet;
[SecurityCritical]
internal SafePerfProviderHandle m_hProvider;
[System.Security.SecurityCritical]
internal PerfProvider(Guid providerGuid) {
m_providerGuid = providerGuid;
uint Status = UnsafeNativeMethods.PerfStartProvider(ref m_providerGuid, null, out m_hProvider);
// ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY
if (Status != (uint) UnsafeNativeMethods.ERROR_SUCCESS) {
throw new Win32Exception((int) Status);
}
}
}
internal static class PerfProviderCollection {
// Internal global PERFLIB V2 provider collection that contains a collection of PerfProvider objects.
// Use mutex to serialize collection initialization/update.
//
private static Object s_hiddenInternalSyncObject;
private static List<PerfProvider> s_providerList = new List<PerfProvider>();
private static Dictionary<Object, Int32> s_counterSetList = new Dictionary<Object, Int32>();
private static CounterType[] s_counterTypes = (CounterType[])Enum.GetValues(typeof(CounterType));
private static CounterSetInstanceType[] s_counterSetInstanceTypes = (CounterSetInstanceType[])Enum.GetValues(typeof(CounterSetInstanceType));
private static Object s_lockObject {
get {
if (s_hiddenInternalSyncObject == null) {
Object o = new Object();
Interlocked.CompareExchange(ref s_hiddenInternalSyncObject, o, null);
}
return s_hiddenInternalSyncObject;
}
}
[System.Security.SecurityCritical]
internal static PerfProvider QueryProvider(Guid providerGuid) {
// Most of the cases should be that the application contains 1 provider that supports several CounterSets;
// that is, ContainsKey should succeed except for the first time.
//
lock (s_lockObject) {
foreach (PerfProvider ProviderEntry in s_providerList) {
if (ProviderEntry.m_providerGuid == providerGuid) {
return ProviderEntry;
}
}
PerfProvider NewProvider = new PerfProvider(providerGuid);
s_providerList.Add(NewProvider);
return NewProvider;
}
}
[System.Security.SecurityCritical]
internal static void RemoveProvider(Guid providerGuid) {
lock (s_lockObject) {
PerfProvider MatchedProvider = null;
foreach (PerfProvider ProviderEntry in s_providerList) {
if (ProviderEntry.m_providerGuid == providerGuid) {
MatchedProvider = ProviderEntry;
}
}
if (MatchedProvider != null) {
MatchedProvider.m_hProvider.Dispose();
s_providerList.Remove(MatchedProvider);
}
}
}
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
internal static void RegisterCounterSet(Guid counterSetGuid) {
// Input counterSetGuid should not be registered yet. That is, ContainsKey() should fail most of times.
//
lock (s_lockObject) {
if (s_counterSetList.ContainsKey(counterSetGuid)) {
throw new ArgumentException(SR.GetString(SR.Perflib_Argument_CounterSetAlreadyRegister, counterSetGuid), "CounterSetGuid");
}
s_counterSetList.Add(counterSetGuid, 0);
}
}
internal static void UnregisterCounterSet(Guid counterSetGuid) {
lock (s_lockObject) {
s_counterSetList.Remove(counterSetGuid);
}
}
internal static bool ValidateCounterType(CounterType inCounterType) {
foreach (CounterType DefinedCounterType in s_counterTypes) {
if (DefinedCounterType == inCounterType) {
return true;
}
}
return false;
}
internal static bool ValidateCounterSetInstanceType(CounterSetInstanceType inCounterSetInstanceType) {
foreach (CounterSetInstanceType DefinedCounterSetInstanceType in s_counterSetInstanceTypes) {
if (DefinedCounterSetInstanceType == inCounterSetInstanceType) {
return true;
}
}
return false;
}
}
}
|