Imported Upstream version 4.6.0.125

Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-08-03 10:59:49 +00:00
parent a569aebcfd
commit e79aa3c0ed
17047 changed files with 3137615 additions and 392334 deletions

View File

@@ -0,0 +1,45 @@
//------------------------------------------------------------------------------
// <copyright file="AssertSection.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if CONFIGURATION_DEP
using System.Configuration;
namespace System.Diagnostics {
internal class AssertSection : ConfigurationElement {
private static readonly ConfigurationPropertyCollection _properties;
private static readonly ConfigurationProperty _propAssertUIEnabled = new ConfigurationProperty("assertuienabled", typeof(bool), true, ConfigurationPropertyOptions.None);
private static readonly ConfigurationProperty _propLogFile = new ConfigurationProperty("logfilename", typeof(string), String.Empty, ConfigurationPropertyOptions.None);
static AssertSection() {
_properties = new ConfigurationPropertyCollection();
_properties.Add(_propAssertUIEnabled);
_properties.Add(_propLogFile);
}
[ConfigurationProperty("assertuienabled", DefaultValue = true)]
public bool AssertUIEnabled {
get {
return (bool) this[_propAssertUIEnabled];
}
}
[ConfigurationProperty("logfilename", DefaultValue = "")]
public string LogFileName {
get {
return (string) this[_propLogFile];
}
}
protected override ConfigurationPropertyCollection Properties {
get {
return _properties;
}
}
}
}
#endif

View File

@@ -0,0 +1,56 @@
//------------------------------------------------------------------------------
// <copyright file="BooleanSwitch.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
*/
namespace System.Diagnostics {
using System.Diagnostics;
using System;
using System.Security;
using System.Security.Permissions;
/// <devdoc>
/// <para>Provides a simple on/off switch that can be used to control debugging and tracing
/// output.</para>
/// </devdoc>
[SwitchLevel(typeof(bool))]
public class BooleanSwitch : Switch {
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.Diagnostics.BooleanSwitch'/>
/// class.</para>
/// </devdoc>
public BooleanSwitch(string displayName, string description)
: base(displayName, description) {
}
public BooleanSwitch(string displayName, string description, string defaultSwitchValue)
: base(displayName, description, defaultSwitchValue) { }
/// <devdoc>
/// <para>Specifies whether the switch is enabled
/// (<see langword='true'/>) or disabled (<see langword='false'/>).</para>
/// </devdoc>
public bool Enabled {
get {
return (SwitchSetting == 0) ? false : true;
}
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
set {
SwitchSetting = value ? 1 : 0;
}
}
protected override void OnValueChanged() {
bool b;
if (Boolean.TryParse(Value, out b))
SwitchSetting = ( b ? 1 : 0);
else
base.OnValueChanged();
}
}
}

View File

@@ -0,0 +1,31 @@
//------------------------------------------------------------------------------
// <copyright file="TextWriterTraceListener.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
*/
namespace System.Diagnostics {
using System;
using System.IO;
using System.Security.Permissions;
using Microsoft.Win32;
[HostProtection(Synchronization=true)]
public class ConsoleTraceListener : TextWriterTraceListener {
public ConsoleTraceListener() : base (Console.Out) {
}
public ConsoleTraceListener(bool useErrorStream) : base (useErrorStream ? Console.Error : Console.Out) {
}
public override void Close() {
// No resources to clean up.
}
}
}

View File

@@ -0,0 +1,68 @@
//------------------------------------------------------------------------------
// <copyright file="CorrelationManager.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Threading;
using System.Runtime.Remoting.Messaging;
namespace System.Diagnostics {
public class CorrelationManager {
private const string transactionSlotName = "System.Diagnostics.Trace.CorrelationManagerSlot";
private const string activityIdSlotName = "E2ETrace.ActivityID";
internal CorrelationManager() { }
public Guid ActivityId {
get {
Object id = CallContext.LogicalGetData(activityIdSlotName);
if (id != null)
return (Guid) id;
else
return Guid.Empty;
}
set {
CallContext.LogicalSetData(activityIdSlotName, value);
}
}
public Stack LogicalOperationStack {
get {
return GetLogicalOperationStack();
}
}
public void StartLogicalOperation(object operationId) {
if (operationId == null)
throw new ArgumentNullException("operationId");
Stack idStack = GetLogicalOperationStack();
idStack.Push(operationId);
}
public void StartLogicalOperation() {
StartLogicalOperation(Guid.NewGuid());
}
public void StopLogicalOperation() {
Stack idStack = GetLogicalOperationStack();
idStack.Pop();
}
private Stack GetLogicalOperationStack() {
Stack idStack = CallContext.LogicalGetData(transactionSlotName) as Stack;
if (idStack == null) {
idStack = new Stack();
CallContext.LogicalSetData(transactionSlotName, idStack);
}
return idStack;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,231 @@
//------------------------------------------------------------------------------
// <copyright file="DefaultTraceListener.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#define DEBUG
#define TRACE
namespace System.Diagnostics {
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security;
using Microsoft.Win32;
using System.Globalization;
using System.Runtime.Versioning;
/// <devdoc>
/// <para>Provides
/// the default output methods and behavior for tracing.</para>
/// </devdoc>
[HostProtection(Synchronization=true)]
public class DefaultTraceListener : TraceListener {
bool assertUIEnabled;
string logFileName;
bool settingsInitialized;
const int internalWriteSize = 16384;
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.Diagnostics.DefaultTraceListener'/> class with
/// Default as its <see cref='System.Diagnostics.TraceListener.Name'/>.</para>
/// </devdoc>
public DefaultTraceListener()
: base("Default") {
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public bool AssertUiEnabled {
get {
if (!settingsInitialized) InitializeSettings();
return assertUIEnabled;
}
set {
if (!settingsInitialized) InitializeSettings();
assertUIEnabled = value;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public string LogFileName {
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
if (!settingsInitialized) InitializeSettings();
return logFileName;
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
if (!settingsInitialized) InitializeSettings();
logFileName = value;
}
}
/// <devdoc>
/// <para>
/// Emits or displays a message
/// and a stack trace for an assertion that
/// always fails.
/// </para>
/// </devdoc>
public override void Fail(string message) {
Fail(message, null);
}
/// <devdoc>
/// <para>
/// Emits or displays messages and a stack trace for an assertion that
/// always fails.
/// </para>
/// </devdoc>
public override void Fail(string message, string detailMessage) {
StackTrace stack = new StackTrace(true);
int userStackFrameIndex = 0;
string stackTrace;
bool uiPermission = UiPermission;
try {
stackTrace = stack.ToString();
}
catch {
stackTrace = "";
}
WriteAssert(stackTrace, message, detailMessage);
if (AssertUiEnabled && uiPermission) {
AssertWrapper.ShowAssert(stackTrace, stack.GetFrame(userStackFrameIndex), message, detailMessage);
}
}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
private void InitializeSettings() {
// don't use the property setters here to avoid infinite recursion.
#if CONFIGURATION_DEP
assertUIEnabled = DiagnosticsConfiguration.AssertUIEnabled;
logFileName = DiagnosticsConfiguration.LogFileName;
#endif
settingsInitialized = true;
}
private void WriteAssert(string stackTrace, string message, string detailMessage) {
string assertMessage = SR.GetString(SR.DebugAssertBanner) + Environment.NewLine
+ SR.GetString(SR.DebugAssertShortMessage) + Environment.NewLine
+ message + Environment.NewLine
+ SR.GetString(SR.DebugAssertLongMessage) + Environment.NewLine +
detailMessage + Environment.NewLine
+ stackTrace;
WriteLine(assertMessage);
}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
private void WriteToLogFile(string message, bool useWriteLine) {
try {
FileInfo file = new FileInfo(LogFileName);
using (Stream stream = file.Open(FileMode.OpenOrCreate)) {
using (StreamWriter writer = new StreamWriter(stream)) {
stream.Position = stream.Length;
if (useWriteLine)
writer.WriteLine(message);
else
writer.Write(message);
}
}
}
catch (Exception e) {
WriteLine(SR.GetString(SR.ExceptionOccurred, LogFileName, e.ToString()), false);
}
}
/// <devdoc>
/// <para>
/// Writes the output to the OutputDebugString
/// API and
/// to System.Diagnostics.Debugger.Log.
/// </para>
/// </devdoc>
public override void Write(string message) {
Write(message, true);
}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
private void Write(string message, bool useLogFile) {
if (NeedIndent) WriteIndent();
// really huge messages mess up both VS and dbmon, so we chop it up into
// reasonable chunks if it's too big
if (message == null || message.Length <= internalWriteSize) {
internalWrite(message);
}
else {
int offset;
for (offset = 0; offset < message.Length - internalWriteSize; offset += internalWriteSize) {
internalWrite(message.Substring(offset, internalWriteSize));
}
internalWrite(message.Substring(offset));
}
if (useLogFile && LogFileName.Length != 0)
WriteToLogFile(message, false);
}
void internalWrite(string message) {
if (Debugger.IsLogging()) {
Debugger.Log(0, null, message);
} else {
if (message == null)
SafeNativeMethods.OutputDebugString(String.Empty);
else
SafeNativeMethods.OutputDebugString(message);
}
}
/// <devdoc>
/// <para>
/// Writes the output to the OutputDebugString
/// API and to System.Diagnostics.Debugger.Log
/// followed by a line terminator.
/// </para>
/// </devdoc>
public override void WriteLine(string message) {
WriteLine(message, true);
}
private void WriteLine(string message, bool useLogFile) {
if (NeedIndent) WriteIndent();
// I do the concat here to make sure it goes as one call to the output.
// we would save a stringbuilder operation by calling Write twice.
Write(message + Environment.NewLine, useLogFile);
NeedIndent = true;
}
/// <devdoc>
/// It returns true if the current permission set allows an assert dialog to be displayed.
/// </devdoc>
private static bool UiPermission {
get {
bool uiPermission = false;
try {
new UIPermission(UIPermissionWindow.SafeSubWindows).Demand();
uiPermission = true;
}
catch {
}
return uiPermission;
}
}
}
}

View File

@@ -0,0 +1,240 @@
//------------------------------------------------------------------------------
// <copyright file="DelimitedListTraceListener.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Text;
using System.Globalization;
using System.IO;
using System.Collections;
using System.Security.Permissions;
using System.Runtime.Versioning;
namespace System.Diagnostics {
[HostProtection(Synchronization=true)]
public class DelimitedListTraceListener : TextWriterTraceListener {
string delimiter = ";";
string secondaryDelim = ",";
bool initializedDelim = false;
public DelimitedListTraceListener(Stream stream) : base(stream) {
}
public DelimitedListTraceListener(Stream stream, string name) : base(stream, name) {
}
public DelimitedListTraceListener(TextWriter writer) : base(writer) {
}
public DelimitedListTraceListener(TextWriter writer, string name) : base(writer, name) {
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
public DelimitedListTraceListener(string fileName) : base (fileName) {
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
public DelimitedListTraceListener(string fileName, string name) : base(fileName, name) {
}
public string Delimiter {
get {
lock(this) { // Probably overkill
if (!initializedDelim) {
if (Attributes.ContainsKey("delimiter"))
delimiter = Attributes["delimiter"];
initializedDelim = true;
}
}
return delimiter;
}
set {
if (value == null)
throw new ArgumentNullException("Delimiter");
if (value.Length == 0)
throw new ArgumentException(SR.GetString("Generic_ArgCantBeEmptyString", "Delimiter"));
lock(this) {
delimiter = value;
initializedDelim = true;
}
if (delimiter == ",")
secondaryDelim = ";";
else
secondaryDelim = ",";
}
}
protected override internal string[] GetSupportedAttributes() {
return new String[]{"delimiter"};
}
public override void TraceEvent(TraceEventCache eventCache, String source, TraceEventType eventType, int id, string format, params object[] args) {
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, format, args))
return;
WriteHeader(source, eventType, id);
if (args != null)
WriteEscaped(String.Format(CultureInfo.InvariantCulture, format, args));
else
WriteEscaped(format);
Write(Delimiter); // Use get_Delimiter
// one more delimiter for the data object
Write(Delimiter); // Use get_Delimiter
WriteFooter(eventCache);
}
public override void TraceEvent(TraceEventCache eventCache, String source, TraceEventType eventType, int id, string message) {
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, message))
return;
WriteHeader(source, eventType, id);
WriteEscaped(message);
Write(Delimiter); // Use get_Delimiter
// one more delimiter for the data object
Write(Delimiter); // Use get_Delimiter
WriteFooter(eventCache);
}
public override void TraceData(TraceEventCache eventCache, String source, TraceEventType eventType, int id, object data) {
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, data))
return;
WriteHeader(source, eventType, id);
// first a delimiter for the message
Write(Delimiter); // Use get_Delimiter
WriteEscaped(data.ToString());
Write(Delimiter); // Use get_Delimiter
WriteFooter(eventCache);
}
public override void TraceData(TraceEventCache eventCache, String source, TraceEventType eventType, int id, params object[] data) {
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, data))
return;
WriteHeader(source, eventType, id);
// first a delimiter for the message
Write(Delimiter); // Use get_Delimiter
if (data != null) {
for (int i=0; i<data.Length; i++) {
if (i != 0)
Write(secondaryDelim);
WriteEscaped(data[i].ToString());
}
}
Write(Delimiter); // Use get_Delimiter
WriteFooter(eventCache);
}
private void WriteHeader(String source, TraceEventType eventType, int id) {
WriteEscaped(source);
Write(Delimiter); // Use get_Delimiter
Write(eventType.ToString());
Write(Delimiter); // Use get_Delimiter
Write(id.ToString(CultureInfo.InvariantCulture));
Write(Delimiter); // Use get_Delimiter
}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
private void WriteFooter(TraceEventCache eventCache) {
if (eventCache != null) {
if (IsEnabled(TraceOptions.ProcessId))
Write(eventCache.ProcessId.ToString(CultureInfo.InvariantCulture));
Write(Delimiter); // Use get_Delimiter
if (IsEnabled(TraceOptions.LogicalOperationStack))
WriteStackEscaped(eventCache.LogicalOperationStack);
Write(Delimiter); // Use get_Delimiter
if (IsEnabled(TraceOptions.ThreadId))
WriteEscaped(eventCache.ThreadId.ToString(CultureInfo.InvariantCulture));
Write(Delimiter); // Use get_Delimiter
if (IsEnabled(TraceOptions.DateTime))
WriteEscaped(eventCache.DateTime.ToString("o", CultureInfo.InvariantCulture));
Write(Delimiter); // Use get_Delimiter
if (IsEnabled(TraceOptions.Timestamp))
Write(eventCache.Timestamp.ToString(CultureInfo.InvariantCulture));
Write(Delimiter); // Use get_Delimiter
if (IsEnabled(TraceOptions.Callstack))
WriteEscaped(eventCache.Callstack);
}
else {
for (int i=0; i<5; i++)
Write(Delimiter); // Use get_Delimiter
}
WriteLine("");
}
private void WriteEscaped(string message) {
if (!String.IsNullOrEmpty(message)) {
StringBuilder sb = new StringBuilder("\"");
int index;
int lastindex = 0;
while((index = message.IndexOf('"', lastindex)) != -1) {
sb.Append(message, lastindex, index - lastindex);
sb.Append("\"\"");
lastindex = index + 1;
}
sb.Append(message, lastindex, message.Length - lastindex);
sb.Append("\"");
Write(sb.ToString());
}
}
private void WriteStackEscaped(Stack stack) {
StringBuilder sb = new StringBuilder("\"");
bool first = true;
foreach (Object obj in stack) {
if (!first)
sb.Append(", ");
else
first = false;
string operation = obj.ToString();
int index;
int lastindex = 0;
while((index = operation.IndexOf('"', lastindex)) != -1) {
sb.Append(operation, lastindex, index - lastindex);
sb.Append("\"\"");
lastindex = index + 1;
}
sb.Append(operation, lastindex, operation.Length - lastindex);
}
sb.Append("\"");
Write(sb.ToString());
}
}
}

View File

@@ -0,0 +1,259 @@
//------------------------------------------------------------------------------
// <copyright file="DiagnosticsConfiguration.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if CONFIGURATION_DEP
namespace System.Diagnostics {
using System;
using System.Reflection;
using System.Collections;
using System.Configuration;
using System.Threading;
using System.Runtime.Versioning;
internal enum InitState {
NotInitialized,
Initializing,
Initialized
}
internal static class DiagnosticsConfiguration {
private static volatile SystemDiagnosticsSection configSection;
private static volatile InitState initState = InitState.NotInitialized;
// setting for Switch.switchSetting
internal static SwitchElementsCollection SwitchSettings {
get {
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null)
return configSectionSav.Switches;
else
return null;
}
}
// setting for DefaultTraceListener.AssertUIEnabled
internal static bool AssertUIEnabled {
get {
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null && configSectionSav.Assert != null)
return configSectionSav.Assert.AssertUIEnabled;
else
return true; // the default
}
}
internal static string ConfigFilePath {
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null)
return configSectionSav.ElementInformation.Source;
else
return string.Empty; // the default
}
}
// setting for DefaultTraceListener.LogFileName
internal static string LogFileName {
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null && configSectionSav.Assert != null)
return configSectionSav.Assert.LogFileName;
else
return string.Empty; // the default
}
}
// setting for TraceInternal.AutoFlush
internal static bool AutoFlush {
get {
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null && configSectionSav.Trace != null)
return configSectionSav.Trace.AutoFlush;
else
return false; // the default
}
}
// setting for TraceInternal.UseGlobalLock
internal static bool UseGlobalLock {
get {
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null && configSectionSav.Trace != null)
return configSectionSav.Trace.UseGlobalLock;
else
return true; // the default
}
}
// setting for TraceInternal.IndentSize
internal static int IndentSize {
get {
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null && configSectionSav.Trace != null)
return configSectionSav.Trace.IndentSize;
else
return 4; // the default
}
}
#if !FEATURE_PAL // perfcounter
internal static int PerfomanceCountersFileMappingSize {
get {
for (int retryCount = 0; !CanInitialize() && retryCount <= 5; ++retryCount) {
if (retryCount == 5)
return SharedPerformanceCounter.DefaultCountersFileMappingSize;
System.Threading.Thread.Sleep(200);
}
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null && configSectionSav.PerfCounters != null) {
int size = configSectionSav.PerfCounters.FileMappingSize;
if (size < SharedPerformanceCounter.MinCountersFileMappingSize)
size = SharedPerformanceCounter.MinCountersFileMappingSize;
if (size > SharedPerformanceCounter.MaxCountersFileMappingSize)
size = SharedPerformanceCounter.MaxCountersFileMappingSize;
return size;
}
else
return SharedPerformanceCounter.DefaultCountersFileMappingSize;
}
}
#endif // !FEATURE_PAL
internal static ListenerElementsCollection SharedListeners {
get {
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null)
return configSectionSav.SharedListeners;
else
return null;
}
}
internal static SourceElementsCollection Sources {
get {
Initialize();
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null && configSectionSav.Sources != null)
return configSectionSav.Sources;
else
return null;
}
}
internal static SystemDiagnosticsSection SystemDiagnosticsSection {
get {
Initialize();
return configSection;
}
}
private static SystemDiagnosticsSection GetConfigSection() {
SystemDiagnosticsSection configSection = (SystemDiagnosticsSection) PrivilegedConfigurationManager.GetSection("system.diagnostics");
return configSection;
}
internal static bool IsInitializing() {
return initState == InitState.Initializing;
}
internal static bool IsInitialized() {
return initState == InitState.Initialized;
}
internal static bool CanInitialize() {
return (initState != InitState.Initializing) &&
!ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress;
}
internal static void Initialize() {
// Initialize() is also called by other components outside of Trace (such as PerformanceCounter)
// as a result using one lock for this critical section and another for Trace API critical sections
// (such as Trace.WriteLine) could potentially lead to deadlock between 2 threads that are
// executing these critical sections (and consequently obtaining the 2 locks) in the reverse order.
// Using the same lock for DiagnosticsConfiguration as well as TraceInternal avoids this issue.
// Sequential locks on TraceInternal.critSec by the same thread is a non issue for this critical section.
lock (TraceInternal.critSec) {
// because some of the code used to load config also uses diagnostics
// we can't block them while we initialize from config. Therefore we just
// return immediately and they just use the default values.
if ( initState != InitState.NotInitialized ||
ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress) {
return;
}
initState = InitState.Initializing; // used for preventing recursion
try {
configSection = GetConfigSection();
}
finally {
initState = InitState.Initialized;
}
}
}
internal static void Refresh() {
ConfigurationManager.RefreshSection("system.diagnostics");
// There might still be some persistant state left behind for
// ConfigPropertyCollection (for ex, swtichelements), probably for perf.
// We need to explicitly cleanup any unrecognized attributes that we
// have added during last deserialization, so that they are re-added
// during the next Config.GetSection properly and we get a chance to
// populate the Attributes collection for re-deserialization.
// Another alternative could be to expose the properties collection
// directly as Attributes collection (currently we keep a local
// hashtable which we explicitly need to keep in sycn and hence the
// cleanup logic below) but the down side of that would be we need to
// explicitly compute what is recognized Vs unrecognized from that
// collection when we expose the unrecognized Attributes publically
SystemDiagnosticsSection configSectionSav = configSection;
if (configSectionSav != null) {
if (configSectionSav.Switches != null) {
foreach (SwitchElement swelem in configSectionSav.Switches)
swelem.ResetProperties();
}
if (configSectionSav.SharedListeners != null) {
foreach (ListenerElement lnelem in configSectionSav.SharedListeners)
lnelem.ResetProperties();
}
if (configSectionSav.Sources != null) {
foreach (SourceElement srelem in configSectionSav.Sources)
srelem.ResetProperties();
}
}
configSection = null;
initState = InitState.NotInitialized;
Initialize();
}
}
}
#endif

View File

@@ -0,0 +1,33 @@
//------------------------------------------------------------------------------
// <copyright file="FilterElement.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if CONFIGURATION_DEP
using System.Configuration;
using System;
namespace System.Diagnostics {
internal class FilterElement : TypedElement {
public FilterElement() : base(typeof(TraceFilter)) {}
public TraceFilter GetRuntimeObject() {
TraceFilter newFilter = (TraceFilter) BaseGetRuntimeObject();
newFilter.initializeData = InitData;
return newFilter;
}
internal TraceFilter RefreshRuntimeObject(TraceFilter filter) {
if (Type.GetType(TypeName) != filter.GetType() || InitData != filter.initializeData) {
// type or initdata changed
_runtimeObject = null;
return GetRuntimeObject();
}
else {
return filter;
}
}
}
}
#endif

View File

@@ -0,0 +1,376 @@
//------------------------------------------------------------------------------
// <copyright file="ListenerElementsCollection.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if CONFIGURATION_DEP
using System.Configuration;
using System;
using System.Reflection;
using System.Globalization;
using System.Xml;
using System.Collections.Specialized;
using System.Collections;
using System.Security;
using System.Security.Permissions;
namespace System.Diagnostics {
[ConfigurationCollection(typeof(ListenerElement))]
internal class ListenerElementsCollection : ConfigurationElementCollection {
new public ListenerElement this[string name] {
get {
return (ListenerElement) BaseGet(name);
}
}
public override ConfigurationElementCollectionType CollectionType {
get {
return ConfigurationElementCollectionType.AddRemoveClearMap;
}
}
protected override ConfigurationElement CreateNewElement() {
return new ListenerElement(true);
}
protected override Object GetElementKey(ConfigurationElement element) {
return ((ListenerElement) element).Name;
}
public TraceListenerCollection GetRuntimeObject() {
TraceListenerCollection listeners = new TraceListenerCollection();
bool _isDemanded = false;
foreach(ListenerElement element in this) {
// At some point, we need to pull out adding/removing the 'default' DefaultTraceListener
// code from here in favor of adding/not-adding after we load the config (in TraceSource
// and in static Trace)
if (!_isDemanded && !element._isAddedByDefault) {
// Do a full damand; This will disable partially trusted code from hooking up listeners
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
_isDemanded = true;
}
listeners.Add(element.GetRuntimeObject());
}
return listeners;
}
protected override void InitializeDefault() {
InitializeDefaultInternal();
}
internal void InitializeDefaultInternal() {
ListenerElement defaultListener = new ListenerElement(false);
defaultListener.Name = "Default";
defaultListener.TypeName = typeof(DefaultTraceListener).FullName;
defaultListener._isAddedByDefault = true;
this.BaseAdd(defaultListener);
}
protected override void BaseAdd(ConfigurationElement element) {
ListenerElement listenerElement = element as ListenerElement;
Debug.Assert((listenerElement != null), "adding elements other than ListenerElement to ListenerElementsCollection?");
if (listenerElement.Name.Equals("Default") && listenerElement.TypeName.Equals(typeof(DefaultTraceListener).FullName))
BaseAdd(listenerElement, false);
else
BaseAdd(listenerElement, ThrowOnDuplicate);
}
}
// This is the collection used by the sharedListener section. It is only slightly different from ListenerElementsCollection.
// The differences are that it does not allow remove and clear, and that the ListenerElements it creates do not allow
// references.
[ConfigurationCollection(typeof(ListenerElement), AddItemName = "add",
CollectionType = ConfigurationElementCollectionType.BasicMap)]
internal class SharedListenerElementsCollection : ListenerElementsCollection {
public override ConfigurationElementCollectionType CollectionType {
get {
return ConfigurationElementCollectionType.BasicMap;
}
}
protected override ConfigurationElement CreateNewElement() {
return new ListenerElement(false);
}
protected override string ElementName {
get {
return "add";
}
}
}
internal class ListenerElement : TypedElement {
private static readonly ConfigurationProperty _propFilter = new ConfigurationProperty("filter", typeof(FilterElement), null, ConfigurationPropertyOptions.None);
private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey);
private static readonly ConfigurationProperty _propOutputOpts = new ConfigurationProperty("traceOutputOptions", typeof(TraceOptions), TraceOptions.None, ConfigurationPropertyOptions.None);
private ConfigurationProperty _propListenerTypeName;
private bool _allowReferences;
private Hashtable _attributes;
internal bool _isAddedByDefault;
static ListenerElement() {
}
public ListenerElement(bool allowReferences) : base(typeof(TraceListener)) {
_allowReferences = allowReferences;
ConfigurationPropertyOptions flags = ConfigurationPropertyOptions.None;
if (!_allowReferences)
flags |= ConfigurationPropertyOptions.IsRequired;
_propListenerTypeName = new ConfigurationProperty("type", typeof(string), null, flags);
_properties.Remove("type");
_properties.Add(_propListenerTypeName);
_properties.Add(_propFilter);
_properties.Add(_propName);
_properties.Add(_propOutputOpts);
}
public Hashtable Attributes {
get {
if (_attributes == null)
_attributes = new Hashtable(StringComparer.OrdinalIgnoreCase);
return _attributes;
}
}
[ConfigurationProperty("filter")]
public FilterElement Filter {
get {
return (FilterElement) this[_propFilter];
}
}
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name {
get {
return (string) this[_propName];
}
set {
this[_propName] = value;
}
}
[ConfigurationProperty("traceOutputOptions", DefaultValue = (TraceOptions) TraceOptions.None)]
public TraceOptions TraceOutputOptions {
get {
return (TraceOptions) this[_propOutputOpts];
}
// This is useful when the OM becomes public. In the meantime, this can be utilized via reflection
set {
this[_propOutputOpts] = value;
}
}
[ConfigurationProperty("type")]
public override string TypeName {
get {
return (string) this[_propListenerTypeName];
}
set {
this[_propListenerTypeName] = value;
}
}
public override bool Equals(object compareTo) {
if (this.Name.Equals("Default") && this.TypeName.Equals(typeof(DefaultTraceListener).FullName)) {
// This is a workaround to treat all DefaultTraceListener named 'Default' the same.
// This is needed for the Config.Save to work properly as otherwise config base layers
// above us would run into duplicate 'Default' listener element and perceive it as
// error.
ListenerElement compareToElem = compareTo as ListenerElement;
return (compareToElem != null) && compareToElem.Name.Equals("Default")
&& compareToElem.TypeName.Equals(typeof(DefaultTraceListener).FullName);
}
else
return base.Equals(compareTo);
}
public override int GetHashCode() {
return base.GetHashCode();
}
public TraceListener GetRuntimeObject() {
if (_runtimeObject != null)
return (TraceListener) _runtimeObject;
try {
string className = TypeName;
if (String.IsNullOrEmpty(className)) {
// Look it up in SharedListeners
Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null");
if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !String.IsNullOrEmpty(InitData))
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_listener_cant_have_properties, Name));
if (DiagnosticsConfiguration.SharedListeners == null)
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name));
ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name];
if (sharedListener == null)
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name));
else {
_runtimeObject = sharedListener.GetRuntimeObject();
return (TraceListener) _runtimeObject;
}
}
else {
// create a new one
TraceListener newListener = (TraceListener) BaseGetRuntimeObject();
newListener.initializeData = InitData;
newListener.Name = Name;
newListener.SetAttributes(Attributes);
newListener.TraceOutputOptions = TraceOutputOptions;
if ((Filter != null) && (Filter.TypeName != null) && (Filter.TypeName.Length != 0)) {
newListener.Filter = Filter.GetRuntimeObject();
XmlWriterTraceListener listerAsXmlWriter = newListener as XmlWriterTraceListener;
if (listerAsXmlWriter != null) {
// This filter was added via configuration, which means we want the listener
// to respect it for TraceTransfer events.
listerAsXmlWriter.shouldRespectFilterOnTraceTransfer = true;
}
}
_runtimeObject = newListener;
return newListener;
}
}
catch (ArgumentException e) {
throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_create_listener, Name), e);
}
}
// Our optional attributes implementation is little convoluted as there is
// no such firsclass mechanism from the config system. We basically cache
// any "unrecognized" attribute here and serialize it out later.
protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) {
Attributes.Add(name, value);
return true;
}
// We need to serialize optional attributes here, a better place would have
// been inside SerializeElement but the base class implementation from
// ConfigurationElement doesn't take into account for derived class doing
// extended serialization, it basically writes out child element that
// forces the element closing syntax, so any attribute serialization needs
// to happen before normal element serialization from ConfigurationElement.
// This means we would write out custom attributes ahead of normal ones.
// The other alternative would be to re-implement the entire routine here
// which is an overkill and a maintenance issue.
protected override void PreSerialize(XmlWriter writer) {
if (_attributes != null) {
IDictionaryEnumerator e = _attributes.GetEnumerator();
while (e.MoveNext()) {
string xmlValue = (string)e.Value;
string xmlName = (string)e.Key;
if ((xmlValue != null) && (writer != null)) {
writer.WriteAttributeString(xmlName, xmlValue);
}
}
}
}
// Account for optional attributes from custom listeners.
protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) {
bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey);
DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0));
return DataToWrite;
}
protected override void Unmerge(ConfigurationElement sourceElement,
ConfigurationElement parentElement,
ConfigurationSaveMode saveMode) {
base.Unmerge(sourceElement, parentElement, saveMode);
// Unmerge the optional attributes cache as well
ListenerElement le = sourceElement as ListenerElement;
if ((le != null) && (le._attributes != null))
this._attributes = le._attributes;
}
internal void ResetProperties()
{
// blow away any UnrecognizedAttributes that we have deserialized earlier
if (_attributes != null) {
_attributes.Clear();
_properties.Clear();
_properties.Add(_propListenerTypeName);
_properties.Add(_propFilter);
_properties.Add(_propName);
_properties.Add(_propOutputOpts);
}
}
internal TraceListener RefreshRuntimeObject(TraceListener listener) {
_runtimeObject = null;
try {
string className = TypeName;
if (String.IsNullOrEmpty(className)) {
// Look it up in SharedListeners and ask the sharedListener to refresh.
Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null");
if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !String.IsNullOrEmpty(InitData))
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_listener_cant_have_properties, Name));
if (DiagnosticsConfiguration.SharedListeners == null)
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name));
ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name];
if (sharedListener == null)
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name));
else {
_runtimeObject = sharedListener.RefreshRuntimeObject(listener);
return (TraceListener) _runtimeObject;
}
}
else {
// We're the element with the type and initializeData info. First see if those two are the same as they were.
// If not, create a whole new object, otherwise, just update the other properties.
if (Type.GetType(className) != listener.GetType() || InitData != listener.initializeData) {
// type or initdata changed
return GetRuntimeObject();
}
else {
listener.SetAttributes(Attributes);
listener.TraceOutputOptions = TraceOutputOptions;
if (listener.Filter != null ) {
if (ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere ||
ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.Inherited)
listener.Filter = Filter.RefreshRuntimeObject(listener.Filter);
else
listener.Filter = null;
}
_runtimeObject = listener;
return listener;
}
}
}
catch (ArgumentException e) {
throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_create_listener, Name), e);
}
}
}
}
#endif

View File

@@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
// <copyright file="PerfCounterSection.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if CONFIGURATION_DEP
using System.Configuration;
namespace System.Diagnostics {
internal class PerfCounterSection : ConfigurationElement {
private static readonly ConfigurationPropertyCollection _properties;
private static readonly ConfigurationProperty _propFileMappingSize = new ConfigurationProperty("filemappingsize", typeof(int), 524288, ConfigurationPropertyOptions.None);
static PerfCounterSection(){
_properties = new ConfigurationPropertyCollection();
_properties.Add(_propFileMappingSize);
}
[ConfigurationProperty("filemappingsize", DefaultValue = 524288)]
public int FileMappingSize {
get {
return (int) this[_propFileMappingSize];
}
}
protected override ConfigurationPropertyCollection Properties {
get {
return _properties;
}
}
}
}
#endif

View File

@@ -0,0 +1,32 @@
//------------------------------------------------------------------------------
// <copyright file="SeverityFilter.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
namespace System.Diagnostics {
public class EventTypeFilter : TraceFilter {
private SourceLevels level;
public EventTypeFilter(SourceLevels level) {
this.level = level;
}
public override bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage,
object[] args, object data1, object[] data) {
return ((int) eventType & (int) level) != 0;
}
public SourceLevels EventType {
get {
return level;
}
set {
level = value;
}
}
}
}

View File

@@ -0,0 +1,190 @@
//------------------------------------------------------------------------------
// <copyright file="SourceElementsCollection .cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if CONFIGURATION_DEP
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Xml;
namespace System.Diagnostics {
[ConfigurationCollection(typeof(SourceElement), AddItemName = "source",
CollectionType = ConfigurationElementCollectionType.BasicMap)]
internal class SourceElementsCollection : ConfigurationElementCollection {
new public SourceElement this[string name] {
get {
return (SourceElement) BaseGet(name);
}
}
protected override string ElementName {
get {
return "source";
}
}
public override ConfigurationElementCollectionType CollectionType {
get {
return ConfigurationElementCollectionType.BasicMap;
}
}
protected override ConfigurationElement CreateNewElement() {
SourceElement se = new SourceElement();
se.Listeners.InitializeDefaultInternal();
return se;
}
protected override Object GetElementKey(ConfigurationElement element) {
return ((SourceElement) element).Name;
}
}
internal class SourceElement : ConfigurationElement {
private static readonly ConfigurationPropertyCollection _properties;
private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired);
private static readonly ConfigurationProperty _propSwitchName = new ConfigurationProperty("switchName", typeof(string), null, ConfigurationPropertyOptions.None);
private static readonly ConfigurationProperty _propSwitchValue = new ConfigurationProperty("switchValue", typeof(string), null, ConfigurationPropertyOptions.None);
private static readonly ConfigurationProperty _propSwitchType = new ConfigurationProperty("switchType", typeof(string), null, ConfigurationPropertyOptions.None);
private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), new ListenerElementsCollection(), ConfigurationPropertyOptions.None);
private Hashtable _attributes;
static SourceElement() {
_properties = new ConfigurationPropertyCollection();
_properties.Add(_propName);
_properties.Add(_propSwitchName);
_properties.Add(_propSwitchValue);
_properties.Add(_propSwitchType);
_properties.Add(_propListeners);
}
public Hashtable Attributes {
get {
if (_attributes == null)
_attributes = new Hashtable(StringComparer.OrdinalIgnoreCase);
return _attributes;
}
}
[ConfigurationProperty("listeners")]
public ListenerElementsCollection Listeners {
get {
return (ListenerElementsCollection) this[_propListeners];
}
}
[ConfigurationProperty("name", IsRequired=true, DefaultValue="")]
public string Name {
get {
return (string) this[_propName];
}
}
protected override ConfigurationPropertyCollection Properties {
get {
return _properties;
}
}
[ConfigurationProperty("switchName")]
public string SwitchName {
get {
return (string) this[_propSwitchName];
}
}
[ConfigurationProperty("switchValue")]
public string SwitchValue {
get {
return (string) this[_propSwitchValue];
}
}
[ConfigurationProperty("switchType")]
public string SwitchType {
get {
return (string) this[_propSwitchType];
}
}
protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
{
base.DeserializeElement(reader, serializeCollectionKey);
if (!String.IsNullOrEmpty(SwitchName) && !String.IsNullOrEmpty(SwitchValue))
throw new ConfigurationErrorsException(SR.GetString(SR.Only_specify_one, Name));
}
// Our optional attributes implementation is little convoluted as there is
// no such firsclass mechanism from the config system. We basically cache
// any "unrecognized" attribute here and serialize it out later.
protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) {
Attributes.Add(name, value);
return true;
}
// We need to serialize optional attributes here, a better place would have
// been inside SerializeElement but the base class implementation from
// ConfigurationElement doesn't take into account for derived class doing
// extended serialization, it basically writes out child element that
// forces the element closing syntax, so any attribute serialization needs
// to happen before normal element serialization from ConfigurationElement.
// This means we would write out custom attributes ahead of normal ones.
// The other alternative would be to re-implement the entire routine here
// which is an overkill and a maintenance issue.
protected override void PreSerialize(XmlWriter writer) {
if (_attributes != null) {
IDictionaryEnumerator e = _attributes.GetEnumerator();
while (e.MoveNext()) {
string xmlValue = (string)e.Value;
string xmlName = (string)e.Key;
if ((xmlValue != null) && (writer != null)) {
writer.WriteAttributeString(xmlName, xmlValue);
}
}
}
}
// Account for optional attributes from custom listeners.
protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) {
bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey);
DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0));
return DataToWrite;
}
protected override void Unmerge(ConfigurationElement sourceElement,
ConfigurationElement parentElement,
ConfigurationSaveMode saveMode) {
base.Unmerge(sourceElement, parentElement, saveMode);
// Unmerge the optional attributes cache as well
SourceElement le = sourceElement as SourceElement;
if ((le != null) && (le._attributes != null))
this._attributes = le._attributes;
}
internal void ResetProperties()
{
// blow away any UnrecognizedAttributes that we have deserialized earlier
if (_attributes != null) {
_attributes.Clear();
_properties.Clear();
_properties.Add(_propName);
_properties.Add(_propSwitchName);
_properties.Add(_propSwitchValue);
_properties.Add(_propSwitchType);
_properties.Add(_propListeners);
}
}
}
}
#endif

View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------------
// <copyright file="SourceFilter.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Collections;
namespace System.Diagnostics {
public class SourceFilter : TraceFilter {
private string src;
public SourceFilter(string source) {
Source = source;
}
public override bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage,
object[] args, object data1, object[] data) {
if (source == null)
throw new ArgumentNullException("source");
return String.Equals(src, source);
}
public String Source {
get {
return src;
}
set {
if (value == null)
throw new ArgumentNullException("source");
src = value;
}
}
}
}

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <copyright file="SourceLevels.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.ComponentModel;
namespace System.Diagnostics {
[Flags]
public enum SourceLevels {
Off = 0,
Critical = 0x01,
Error = 0x03,
Warning = 0x07,
Information = 0x0F,
Verbose = 0x1F,
[EditorBrowsable(EditorBrowsableState.Advanced)]
ActivityTracing = 0xFF00,
All = unchecked ((int) 0xFFFFFFFF),
}
}

View File

@@ -0,0 +1,39 @@
//------------------------------------------------------------------------------
// <copyright file="SourceSwitch.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Threading;
using System.Security;
using System.Security.Permissions;
namespace System.Diagnostics {
public class SourceSwitch : Switch {
public SourceSwitch(string name) : base(name, String.Empty) {}
public SourceSwitch(string displayName, string defaultSwitchValue)
: base(displayName, String.Empty, defaultSwitchValue) { }
public SourceLevels Level {
get {
return (SourceLevels) SwitchSetting;
}
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
set {
SwitchSetting = (int) value;
}
}
public bool ShouldTrace(TraceEventType eventType) {
return (SwitchSetting & (int) eventType) != 0;
}
protected override void OnValueChanged() {
SwitchSetting = (int) Enum.Parse(typeof(SourceLevels), Value, true);
}
}
}

View File

@@ -0,0 +1,317 @@
//------------------------------------------------------------------------------
// <copyright file="Switch.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
*/
#if !CONFIGURATION_DEP
using SwitchElementsCollection = System.Object;
#endif
namespace System.Diagnostics {
using System;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Configuration;
#if XML_DEP
using System.Xml.Serialization;
#endif
using System.Diagnostics.CodeAnalysis;
/// <devdoc>
/// <para>Provides an <see langword='abstract '/>base class to
/// create new debugging and tracing switches.</para>
/// </devdoc>
public abstract class Switch {
private SwitchElementsCollection switchSettings;
private readonly string description;
private readonly string displayName;
private int switchSetting = 0;
private volatile bool initialized = false;
private bool initializing = false;
private volatile string switchValueString = String.Empty;
private StringDictionary attributes;
private string defaultValue;
private object m_intializedLock;
private static List<WeakReference> switches = new List<WeakReference>();
private static int s_LastCollectionCount;
private object IntializedLock {
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety")]
get {
if (m_intializedLock == null) {
Object o = new Object();
Interlocked.CompareExchange<Object>(ref m_intializedLock, o, null);
}
return m_intializedLock;
}
}
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.Diagnostics.Switch'/>
/// class.</para>
/// </devdoc>
protected Switch(string displayName, string description) : this(displayName, description, "0") {
}
protected Switch(string displayName, string description, string defaultSwitchValue) {
// displayName is used as a hashtable key, so it can never
// be null.
if (displayName == null) displayName = string.Empty;
this.displayName = displayName;
this.description = description;
// Add a weakreference to this switch and cleanup invalid references
lock (switches) {
_pruneCachedSwitches();
switches.Add(new WeakReference(this));
}
defaultValue = defaultSwitchValue;
}
private static void _pruneCachedSwitches() {
lock (switches) {
if (s_LastCollectionCount != GC.CollectionCount(2)) {
List<WeakReference> buffer = new List<WeakReference>(switches.Count);
for (int i = 0; i < switches.Count; i++) {
Switch s = ((Switch)switches[i].Target);
if (s != null) {
buffer.Add(switches[i]);
}
}
if (buffer.Count < switches.Count) {
switches.Clear();
switches.AddRange(buffer);
switches.TrimExcess();
}
s_LastCollectionCount = GC.CollectionCount(2);
}
}
}
#if XML_DEP
[XmlIgnore]
#endif
public StringDictionary Attributes {
get {
Initialize();
if (attributes == null)
attributes = new StringDictionary();
return attributes;
}
}
/// <devdoc>
/// <para>Gets a name used to identify the switch.</para>
/// </devdoc>
public string DisplayName {
get {
return displayName;
}
}
/// <devdoc>
/// <para>Gets a description of the switch.</para>
/// </devdoc>
public string Description {
get {
return (description == null) ? string.Empty : description;
}
}
/// <devdoc>
/// <para>
/// Indicates the current setting for this switch.
/// </para>
/// </devdoc>
protected int SwitchSetting {
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "reviewed for thread-safety")]
get {
if (!initialized) {
if (InitializeWithStatus())
OnSwitchSettingChanged();
}
return switchSetting;
}
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "reviewed for thread-safety")]
set {
bool didUpdate = false;
lock (IntializedLock) {
initialized = true;
if (switchSetting != value) {
switchSetting = value;
didUpdate = true;
}
}
if (didUpdate) {
OnSwitchSettingChanged();
}
}
}
protected string Value {
get {
Initialize();
return switchValueString;
}
set {
Initialize();
switchValueString = value;
#if CONFIGURATION_DEP
try {
OnValueChanged();
}
catch (ArgumentException e) {
throw new ConfigurationErrorsException(SR.GetString(SR.BadConfigSwitchValue, DisplayName), e);
}
catch (FormatException e) {
throw new ConfigurationErrorsException(SR.GetString(SR.BadConfigSwitchValue, DisplayName), e);
}
catch (OverflowException e) {
throw new ConfigurationErrorsException(SR.GetString(SR.BadConfigSwitchValue, DisplayName), e);
}
#else
OnValueChanged();
#endif
}
}
private void Initialize() {
InitializeWithStatus();
}
private bool InitializeWithStatus() {
if (!initialized) {
lock (IntializedLock) {
if (initialized || initializing) {
return false;
}
// This method is re-entrent during intitialization, since calls to OnValueChanged() in subclasses could end up having InitializeWithStatus()
// called again, we don't want to get caught in an infinite loop.
initializing = true;
if (switchSettings == null) {
if (!InitializeConfigSettings()) {
initialized = true;
initializing = false;
return false;
}
}
#if CONFIGURATION_DEP
if (switchSettings != null) {
SwitchElement mySettings = switchSettings[displayName];
if (mySettings != null) {
string value = mySettings.Value;
if (value != null) {
this.Value = value;
} else
this.Value = defaultValue;
try {
TraceUtils.VerifyAttributes(mySettings.Attributes, GetSupportedAttributes(), this);
} catch (ConfigurationException) {
// if VerifyAttributes throws, clean up a little bit so we're not in a bad state.
initialized = false;
initializing = false;
throw;
}
attributes = new StringDictionary();
attributes.ReplaceHashtable(mySettings.Attributes);
} else {
// We don't use the property here because we don't want to catch exceptions
// and rethrow them as ConfigurationException. In this case there's no config.
switchValueString = defaultValue;
OnValueChanged();
}
} else {
#endif
// We don't use the property here because we don't want to catch exceptions
// and rethrow them as ConfigurationException. In this case there's no config.
switchValueString = defaultValue;
OnValueChanged();
#if CONFIGURATION_DEP
}
#endif
initialized = true;
initializing = false;
}
}
return true;
}
private bool InitializeConfigSettings() {
if (switchSettings != null)
return true;
#if CONFIGURATION_DEP
if (!DiagnosticsConfiguration.CanInitialize())
return false;
// This hashtable is case-insensitive.
switchSettings = DiagnosticsConfiguration.SwitchSettings;
#endif
return true;
}
virtual protected internal string[] GetSupportedAttributes() {
return null;
}
/// <devdoc>
/// This method is invoked when a switch setting has been changed. It will
/// be invoked the first time a switch reads its value from the registry
/// or environment, and then it will be invoked each time the switch's
/// value is changed.
/// </devdoc>
protected virtual void OnSwitchSettingChanged() {
}
protected virtual void OnValueChanged() {
SwitchSetting = Int32.Parse(Value, CultureInfo.InvariantCulture);
}
internal static void RefreshAll() {
lock (switches) {
_pruneCachedSwitches();
for (int i=0; i<switches.Count; i++) {
Switch swtch = ((Switch) switches[i].Target);
if (swtch != null) {
swtch.Refresh();
}
}
}
}
internal void Refresh() {
lock (IntializedLock) {
initialized = false;
switchSettings = null;
Initialize();
}
}
}
}

View File

@@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
// <copyright file="SwitchAttribute.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
using System.Collections;
namespace System.Diagnostics {
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Constructor |
AttributeTargets.Event | AttributeTargets.Method | AttributeTargets.Property)]
public sealed class SwitchAttribute : Attribute {
private Type type;
private string name;
private string description;
public SwitchAttribute (string switchName, Type switchType) {
SwitchName = switchName;
SwitchType = switchType;
}
public string SwitchName {
get { return name; }
set {
if (value == null)
throw new ArgumentNullException("value");
if (value.Length == 0)
throw new ArgumentException(SR.GetString(SR.InvalidNullEmptyArgument, "value"), "value");
name = value;
}
}
public Type SwitchType {
get { return type; }
set {
if (value == null)
throw new ArgumentNullException("value");
type = value;
}
}
public string SwitchDescription {
get { return description; }
set { description = value;}
}
public static SwitchAttribute[] GetAll(Assembly assembly) {
if (assembly == null)
throw new ArgumentNullException("assembly");
ArrayList switchAttribs = new ArrayList ();
object[] attribs = assembly.GetCustomAttributes(typeof(SwitchAttribute), false);
switchAttribs.AddRange(attribs);
Type[] types = assembly.GetTypes();
for (int i=0; i<types.Length; i++)
GetAllRecursive(types[i], switchAttribs);
SwitchAttribute[] ret = new SwitchAttribute[switchAttribs.Count];
switchAttribs.CopyTo(ret, 0);
return ret;
}
static void GetAllRecursive(Type type, ArrayList switchAttribs) {
GetAllRecursive((MemberInfo) type, switchAttribs);
MemberInfo[] members = type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.DeclaredOnly | BindingFlags.Instance |
BindingFlags.Static);
for (int i=0; i<members.Length; i++) {
// ignore Types here. They will get covered by the top level assembly.GetTypes
if (!(members[i] is Type))
GetAllRecursive(members[i], switchAttribs);
}
}
static void GetAllRecursive(MemberInfo member, ArrayList switchAttribs) {
object[] attribs = member.GetCustomAttributes(typeof(SwitchAttribute), false);
switchAttribs.AddRange(attribs);
}
}
}

View File

@@ -0,0 +1,141 @@
//------------------------------------------------------------------------------
// <copyright file="SwitchElementsCollection.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if CONFIGURATION_DEP
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Xml;
namespace System.Diagnostics {
[ConfigurationCollection(typeof(SwitchElement))]
internal class SwitchElementsCollection : ConfigurationElementCollection {
new public SwitchElement this[string name] {
get {
return (SwitchElement) BaseGet(name);
}
}
public override ConfigurationElementCollectionType CollectionType {
get {
return ConfigurationElementCollectionType.AddRemoveClearMap;
}
}
protected override ConfigurationElement CreateNewElement() {
return new SwitchElement();
}
protected override Object GetElementKey(ConfigurationElement element) {
return ((SwitchElement) element).Name;
}
}
internal class SwitchElement : ConfigurationElement {
private static readonly ConfigurationPropertyCollection _properties;
private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey);
private static readonly ConfigurationProperty _propValue = new ConfigurationProperty("value", typeof(string), null, ConfigurationPropertyOptions.IsRequired);
private Hashtable _attributes;
static SwitchElement(){
_properties = new ConfigurationPropertyCollection();
_properties.Add(_propName);
_properties.Add(_propValue);
}
public Hashtable Attributes {
get {
if (_attributes == null)
_attributes = new Hashtable(StringComparer.OrdinalIgnoreCase);
return _attributes;
}
}
[ConfigurationProperty("name", DefaultValue = "", IsRequired = true, IsKey = true)]
public string Name {
get {
return (string) this[_propName];
}
}
protected override ConfigurationPropertyCollection Properties {
get {
return _properties;
}
}
[ConfigurationProperty("value", IsRequired = true)]
public string Value {
get {
return (string) this[_propValue];
}
}
// Our optional attributes implementation is little convoluted as there is
// no such firsclass mechanism from the config system. We basically cache
// any "unrecognized" attribute here and serialize it out later.
protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) {
Attributes.Add(name, value);
return true;
}
// We need to serialize optional attributes here, a better place would have
// been inside SerializeElement but the base class implementation from
// ConfigurationElement doesn't take into account for derived class doing
// extended serialization, it basically writes out child element that
// forces the element closing syntax, so any attribute serialization needs
// to happen before normal element serialization from ConfigurationElement.
// This means we would write out custom attributes ahead of normal ones.
// The other alternative would be to re-implement the entire routine here
// which is an overkill and a maintenance issue.
protected override void PreSerialize(XmlWriter writer) {
if (_attributes != null) {
IDictionaryEnumerator e = _attributes.GetEnumerator();
while (e.MoveNext()) {
string xmlValue = (string)e.Value;
string xmlName = (string)e.Key;
if ((xmlValue != null) && (writer != null)) {
writer.WriteAttributeString(xmlName, xmlValue);
}
}
}
}
// Account for optional attributes from custom listeners.
protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) {
bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey);
DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0));
return DataToWrite;
}
protected override void Unmerge(ConfigurationElement sourceElement,
ConfigurationElement parentElement,
ConfigurationSaveMode saveMode) {
base.Unmerge(sourceElement, parentElement, saveMode);
// Unmerge the optional attributes cache as well
SwitchElement le = sourceElement as SwitchElement;
if ((le != null) && (le._attributes != null))
this._attributes = le._attributes;
}
internal void ResetProperties()
{
// blow away any UnrecognizedAttributes that we have deserialized earlier
if (_attributes != null) {
_attributes.Clear();
_properties.Clear();
_properties.Add(_propName);
_properties.Add(_propValue);
}
}
}
}
#endif

View File

@@ -0,0 +1,31 @@
//------------------------------------------------------------------------------
// <copyright file="SwitchLevelAttribute .cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
using System.Collections;
namespace System.Diagnostics {
[AttributeUsage(AttributeTargets.Class)]
public sealed class SwitchLevelAttribute : Attribute {
private Type type;
public SwitchLevelAttribute (Type switchLevelType) {
SwitchLevelType = switchLevelType;
}
public Type SwitchLevelType {
get { return type;}
set {
if (value == null)
throw new ArgumentNullException("value");
type = value;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More