1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
//------------------------------------------------------------------------------
// <copyright file="PerfCounters.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
* PerfCounters class
*/
namespace System.Web {
using System.Web.Util;
using System.Threading;
using System.Runtime.InteropServices;
internal sealed class PerfInstanceDataHandle: SafeHandle {
internal PerfInstanceDataHandle() : base(IntPtr.Zero, true) {
}
internal IntPtr UnsafeHandle {
get { return handle; }
}
public override bool IsInvalid {
get { return handle == IntPtr.Zero; }
}
override protected bool ReleaseHandle() {
UnsafeNativeMethods.PerfCloseAppCounters(handle);
handle = IntPtr.Zero;
return true;
}
}
internal sealed class PerfCounters {
// singleton used for providing an abstraction to callers who require an interface implementation
internal static readonly IPerfCounters Instance = new PerfCountersInstance();
private static PerfInstanceDataHandle _instance = null;
private static IntPtr _global = IntPtr.Zero;
private static IntPtr _stateService = IntPtr.Zero;
private PerfCounters () {}
internal static void Open(string appName) {
Debug.Assert(appName != null);
OpenCounter(appName);
}
internal static void OpenStateCounters() {
OpenCounter(null);
}
// The app name should either be a valid app name or be 'null' to get the state service
// counters initialized
private static void OpenCounter(string appName) {
try {
// Don't activate perf counters if webengine.dll isn't loaded
if (! HttpRuntime.IsEngineLoaded)
return;
// Open the global counters
if (_global == IntPtr.Zero) {
_global = UnsafeNativeMethods.PerfOpenGlobalCounters();
}
// If appName is null, then we want the state counters
if (appName == null) {
if (_stateService == IntPtr.Zero) {
_stateService = UnsafeNativeMethods.PerfOpenStateCounters();
}
}
else {
if (appName != null) {
_instance = UnsafeNativeMethods.PerfOpenAppCounters(appName);
}
}
}
catch (Exception e) {
Debug.Trace("Perfcounters", "Exception: " + e.StackTrace);
}
}
// Make sure webengine.dll is loaded before attempting to call into it (ASURT 98531)
internal static void IncrementCounter(AppPerfCounter counter) {
if (_instance != null)
UnsafeNativeMethods.PerfIncrementCounter(_instance.UnsafeHandle, (int) counter);
}
internal static void DecrementCounter(AppPerfCounter counter) {
if (_instance != null)
UnsafeNativeMethods.PerfDecrementCounter(_instance.UnsafeHandle, (int) counter);
}
internal static void IncrementCounterEx(AppPerfCounter counter, int delta) {
if (_instance != null)
UnsafeNativeMethods.PerfIncrementCounterEx(_instance.UnsafeHandle, (int) counter, delta);
}
internal static void SetCounter(AppPerfCounter counter, int value) {
if (_instance != null)
UnsafeNativeMethods.PerfSetCounter(_instance.UnsafeHandle, (int) counter, value);
}
// It's important that this be debug only. We don't want production
// code to access shared memory that another process could corrupt.
#if DBG
internal static int GetCounter(AppPerfCounter counter) {
if (_instance != null)
return UnsafeNativeMethods.PerfGetCounter(_instance.UnsafeHandle, (int) counter);
else
return -1;
}
#endif
internal static int GetGlobalCounter(GlobalPerfCounter counter) {
if (_global != IntPtr.Zero)
return UnsafeNativeMethods.PerfGetCounter(_global, (int) counter);
else
return -1;
}
internal static void IncrementGlobalCounter(GlobalPerfCounter counter) {
if (_global != IntPtr.Zero)
UnsafeNativeMethods.PerfIncrementCounter(_global, (int) counter);
}
internal static void DecrementGlobalCounter(GlobalPerfCounter counter) {
if (_global != IntPtr.Zero)
UnsafeNativeMethods.PerfDecrementCounter(_global, (int) counter);
}
internal static void SetGlobalCounter(GlobalPerfCounter counter, int value) {
if (_global != IntPtr.Zero)
UnsafeNativeMethods.PerfSetCounter(_global, (int) counter, value);
}
internal static void IncrementStateServiceCounter(StateServicePerfCounter counter) {
if (_stateService == IntPtr.Zero)
return;
UnsafeNativeMethods.PerfIncrementCounter(_stateService, (int) counter);
switch (counter) {
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_TOTAL:
IncrementGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_TOTAL);
break;
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_ACTIVE:
IncrementGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_ACTIVE);
break;
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_TIMED_OUT:
IncrementGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_TIMED_OUT);
break;
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_ABANDONED:
IncrementGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_ABANDONED);
break;
default:
break;
}
}
internal static void DecrementStateServiceCounter(StateServicePerfCounter counter) {
if (_stateService == IntPtr.Zero)
return;
UnsafeNativeMethods.PerfDecrementCounter(_stateService, (int) counter);
switch (counter) {
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_TOTAL:
DecrementGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_TOTAL);
break;
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_ACTIVE:
DecrementGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_ACTIVE);
break;
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_TIMED_OUT:
DecrementGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_TIMED_OUT);
break;
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_ABANDONED:
DecrementGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_ABANDONED);
break;
default:
break;
}
}
internal static void SetStateServiceCounter(StateServicePerfCounter counter, int value) {
if (_stateService == IntPtr.Zero)
return;
UnsafeNativeMethods.PerfSetCounter(_stateService, (int) counter, value);
switch (counter) {
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_TOTAL:
SetGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_TOTAL, value);
break;
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_ACTIVE:
SetGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_ACTIVE, value);
break;
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_TIMED_OUT:
SetGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_TIMED_OUT, value);
break;
case StateServicePerfCounter.STATE_SERVICE_SESSIONS_ABANDONED:
SetGlobalCounter(GlobalPerfCounter.STATE_SERVER_SESSIONS_ABANDONED, value);
break;
default:
break;
}
}
private sealed class PerfCountersInstance : IPerfCounters {
public void IncrementCounter(AppPerfCounter counter) {
PerfCounters.IncrementCounter(counter);
}
public void IncrementCounter(AppPerfCounter counter, int value) {
PerfCounters.IncrementCounterEx(counter, value);
}
public void DecrementCounter(AppPerfCounter counter) {
PerfCounters.DecrementCounter(counter);
}
public void SetCounter(AppPerfCounter counter, int value) {
PerfCounters.SetCounter(counter, value);
}
}
};
}
|