|
//------------------------------------------------------------------------------
// <copyright file="CounterSetInstance.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Diagnostics.PerformanceData {
using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Security;
using Microsoft.Win32;
/// <summary>
/// CounterSetInstance class maps to "Instace" in native performance counter implementation.
/// </summary>
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public sealed class CounterSetInstance : IDisposable {
internal CounterSet m_counterSet;
internal String m_instName;
private Int32 m_active;
private CounterSetInstanceCounterDataSet m_counters;
[SecurityCritical]
unsafe internal UnsafeNativeMethods.PerfCounterSetInstanceStruct * m_nativeInst;
[System.Security.SecurityCritical]
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
internal CounterSetInstance(CounterSet counterSetDefined, String instanceName) {
if (counterSetDefined == null) {
throw new ArgumentNullException("counterSetDefined");
}
if (instanceName == null) {
throw new ArgumentNullException("InstanceName");
}
if (instanceName.Length == 0) {
throw new ArgumentException(SR.GetString(SR.Perflib_Argument_EmptyInstanceName), "InstanceName");
}
m_counterSet = counterSetDefined;
m_instName = instanceName;
unsafe {
m_nativeInst = UnsafeNativeMethods.PerfCreateInstance(
m_counterSet.m_provider.m_hProvider, ref m_counterSet.m_counterSet, m_instName, 0);
int Status = (int) ((m_nativeInst != null) ? UnsafeNativeMethods.ERROR_SUCCESS : Marshal.GetLastWin32Error());
if (m_nativeInst != null) {
m_counters = new CounterSetInstanceCounterDataSet(this);
}
else {
// ERROR_INVALID_PARAMETER,
// ERROR_NOT_FOUND (cannot find installed CounterSet),
// ERROR_ALREADY_EXISTS,
// ERROR_NOT_ENOUGH_MEMORY
switch (Status) {
case (int) UnsafeNativeMethods.ERROR_ALREADY_EXISTS:
throw new ArgumentException(SR.GetString(SR.Perflib_Argument_InstanceAlreadyExists, m_instName, m_counterSet.m_counterSet), "InstanceName");
case (int) UnsafeNativeMethods.ERROR_NOT_FOUND:
throw new InvalidOperationException( SR.GetString(SR.Perflib_InvalidOperation_CounterSetNotInstalled, m_counterSet.m_counterSet));
case (int) UnsafeNativeMethods.ERROR_INVALID_PARAMETER:
if (m_counterSet.m_instType == CounterSetInstanceType.Single) {
throw new ArgumentException(SR.GetString(SR.Perflib_Argument_InvalidInstance, m_counterSet.m_counterSet), "InstanceName");
}
else {
throw new Win32Exception(Status);
}
default:
throw new Win32Exception(Status);
}
}
}
m_active = 1;
}
[System.Security.SecurityCritical]
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
[System.Security.SecurityCritical]
~CounterSetInstance() {
Dispose(false);
}
[System.Security.SecurityCritical]
private void Dispose(bool disposing) {
if (disposing) {
if (m_counters != null) {
m_counters.Dispose();
m_counters = null;
}
}
unsafe {
if (m_nativeInst != null) {
if (Interlocked.Exchange(ref m_active, 0) != 0) {
if (m_nativeInst != null) {
lock(m_counterSet) {
if (m_counterSet.m_provider != null) {
uint Status = UnsafeNativeMethods.PerfDeleteInstance(m_counterSet.m_provider.m_hProvider, m_nativeInst);
}
m_nativeInst = null;
}
}
}
}
}
}
/// <summary>
/// Access CounterSetInstanceCounterDataSet property. Developers can then use defined indexer to access
/// specific CounterData object to query/update raw counter data.
/// </summary>
public CounterSetInstanceCounterDataSet Counters {
get { return m_counters; }
}
}
}
|