You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
475
mcs/class/referencesource/mscorlib/system/AggregateException.cs
Normal file
475
mcs/class/referencesource/mscorlib/system/AggregateException.cs
Normal file
@@ -0,0 +1,475 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
//
|
||||
// AggregateException.cs
|
||||
//
|
||||
// <OWNER>[....]</OWNER>
|
||||
//
|
||||
// Public type to communicate multiple failures to an end-user.
|
||||
//
|
||||
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security;
|
||||
using System.Threading;
|
||||
|
||||
namespace System
|
||||
{
|
||||
|
||||
/// <summary>Represents one or more errors that occur during application execution.</summary>
|
||||
/// <remarks>
|
||||
/// <see cref="AggregateException"/> is used to consolidate multiple failures into a single, throwable
|
||||
/// exception object.
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[DebuggerDisplay("Count = {InnerExceptionCount}")]
|
||||
public class AggregateException : Exception
|
||||
{
|
||||
|
||||
private ReadOnlyCollection<Exception> m_innerExceptions; // Complete set of exceptions.
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class.
|
||||
/// </summary>
|
||||
public AggregateException()
|
||||
: base(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"))
|
||||
{
|
||||
m_innerExceptions = new ReadOnlyCollection<Exception>(new Exception[0]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class with
|
||||
/// a specified error message.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
public AggregateException(string message)
|
||||
: base(message)
|
||||
{
|
||||
m_innerExceptions = new ReadOnlyCollection<Exception>(new Exception[0]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class with a specified error
|
||||
/// message and a reference to the inner exception that is the cause of this exception.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="innerException"/> argument
|
||||
/// is null.</exception>
|
||||
public AggregateException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
if (innerException == null)
|
||||
{
|
||||
throw new ArgumentNullException("innerException");
|
||||
}
|
||||
|
||||
m_innerExceptions = new ReadOnlyCollection<Exception>(new Exception[] { innerException });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class with
|
||||
/// references to the inner exceptions that are the cause of this exception.
|
||||
/// </summary>
|
||||
/// <param name="innerExceptions">The exceptions that are the cause of the current exception.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="innerExceptions"/> argument
|
||||
/// is null.</exception>
|
||||
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is
|
||||
/// null.</exception>
|
||||
public AggregateException(IEnumerable<Exception> innerExceptions) :
|
||||
this(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"), innerExceptions)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class with
|
||||
/// references to the inner exceptions that are the cause of this exception.
|
||||
/// </summary>
|
||||
/// <param name="innerExceptions">The exceptions that are the cause of the current exception.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="innerExceptions"/> argument
|
||||
/// is null.</exception>
|
||||
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is
|
||||
/// null.</exception>
|
||||
public AggregateException(params Exception[] innerExceptions) :
|
||||
this(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"), innerExceptions)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class with a specified error
|
||||
/// message and references to the inner exceptions that are the cause of this exception.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerExceptions">The exceptions that are the cause of the current exception.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="innerExceptions"/> argument
|
||||
/// is null.</exception>
|
||||
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is
|
||||
/// null.</exception>
|
||||
public AggregateException(string message, IEnumerable<Exception> innerExceptions)
|
||||
// If it's already an IList, pass that along (a defensive copy will be made in the delegated ctor). If it's null, just pass along
|
||||
// null typed correctly. Otherwise, create an IList from the enumerable and pass that along.
|
||||
: this(message, innerExceptions as IList<Exception> ?? (innerExceptions == null ? (List<Exception>)null : new List<Exception>(innerExceptions)))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class with a specified error
|
||||
/// message and references to the inner exceptions that are the cause of this exception.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerExceptions">The exceptions that are the cause of the current exception.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="innerExceptions"/> argument
|
||||
/// is null.</exception>
|
||||
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is
|
||||
/// null.</exception>
|
||||
public AggregateException(string message, params Exception[] innerExceptions) :
|
||||
this(message, (IList<Exception>)innerExceptions)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allocates a new aggregate exception with the specified message and list of inner exceptions.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerExceptions">The exceptions that are the cause of the current exception.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="innerExceptions"/> argument
|
||||
/// is null.</exception>
|
||||
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is
|
||||
/// null.</exception>
|
||||
private AggregateException(string message, IList<Exception> innerExceptions)
|
||||
: base(message, innerExceptions != null && innerExceptions.Count > 0 ? innerExceptions[0] : null)
|
||||
{
|
||||
if (innerExceptions == null)
|
||||
{
|
||||
throw new ArgumentNullException("innerExceptions");
|
||||
}
|
||||
|
||||
// Copy exceptions to our internal array and validate them. We must copy them,
|
||||
// because we're going to put them into a ReadOnlyCollection which simply reuses
|
||||
// the list passed in to it. We don't want callers subsequently mutating.
|
||||
Exception[] exceptionsCopy = new Exception[innerExceptions.Count];
|
||||
|
||||
for (int i = 0; i < exceptionsCopy.Length; i++)
|
||||
{
|
||||
exceptionsCopy[i] = innerExceptions[i];
|
||||
|
||||
if (exceptionsCopy[i] == null)
|
||||
{
|
||||
throw new ArgumentException(Environment.GetResourceString("AggregateException_ctor_InnerExceptionNull"));
|
||||
}
|
||||
}
|
||||
|
||||
m_innerExceptions = new ReadOnlyCollection<Exception>(exceptionsCopy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class with
|
||||
/// references to the inner exception dispatch info objects that represent the cause of this exception.
|
||||
/// </summary>
|
||||
/// <param name="innerExceptionInfos">
|
||||
/// Information about the exceptions that are the cause of the current exception.
|
||||
/// </param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="innerExceptionInfos"/> argument
|
||||
/// is null.</exception>
|
||||
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptionInfos"/> is
|
||||
/// null.</exception>
|
||||
internal AggregateException(IEnumerable<ExceptionDispatchInfo> innerExceptionInfos) :
|
||||
this(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"), innerExceptionInfos)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class with a specified error
|
||||
/// message and references to the inner exception dispatch info objects that represent the cause of
|
||||
/// this exception.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerExceptionInfos">
|
||||
/// Information about the exceptions that are the cause of the current exception.
|
||||
/// </param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="innerExceptionInfos"/> argument
|
||||
/// is null.</exception>
|
||||
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptionInfos"/> is
|
||||
/// null.</exception>
|
||||
internal AggregateException(string message, IEnumerable<ExceptionDispatchInfo> innerExceptionInfos)
|
||||
// If it's already an IList, pass that along (a defensive copy will be made in the delegated ctor). If it's null, just pass along
|
||||
// null typed correctly. Otherwise, create an IList from the enumerable and pass that along.
|
||||
: this(message, innerExceptionInfos as IList<ExceptionDispatchInfo> ??
|
||||
(innerExceptionInfos == null ?
|
||||
(List<ExceptionDispatchInfo>)null :
|
||||
new List<ExceptionDispatchInfo>(innerExceptionInfos)))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allocates a new aggregate exception with the specified message and list of inner
|
||||
/// exception dispatch info objects.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerExceptionInfos">
|
||||
/// Information about the exceptions that are the cause of the current exception.
|
||||
/// </param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="innerExceptionInfos"/> argument
|
||||
/// is null.</exception>
|
||||
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptionInfos"/> is
|
||||
/// null.</exception>
|
||||
private AggregateException(string message, IList<ExceptionDispatchInfo> innerExceptionInfos)
|
||||
: base(message, innerExceptionInfos != null && innerExceptionInfos.Count > 0 && innerExceptionInfos[0] != null ?
|
||||
innerExceptionInfos[0].SourceException : null)
|
||||
{
|
||||
if (innerExceptionInfos == null)
|
||||
{
|
||||
throw new ArgumentNullException("innerExceptionInfos");
|
||||
}
|
||||
|
||||
// Copy exceptions to our internal array and validate them. We must copy them,
|
||||
// because we're going to put them into a ReadOnlyCollection which simply reuses
|
||||
// the list passed in to it. We don't want callers subsequently mutating.
|
||||
Exception[] exceptionsCopy = new Exception[innerExceptionInfos.Count];
|
||||
|
||||
for (int i = 0; i < exceptionsCopy.Length; i++)
|
||||
{
|
||||
var edi = innerExceptionInfos[i];
|
||||
if (edi != null) exceptionsCopy[i] = edi.SourceException;
|
||||
|
||||
if (exceptionsCopy[i] == null)
|
||||
{
|
||||
throw new ArgumentException(Environment.GetResourceString("AggregateException_ctor_InnerExceptionNull"));
|
||||
}
|
||||
}
|
||||
|
||||
m_innerExceptions = new ReadOnlyCollection<Exception>(exceptionsCopy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AggregateException"/> class with serialized data.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds
|
||||
/// the serialized object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that
|
||||
/// contains contextual information about the source or destination. </param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="info"/> argument is null.</exception>
|
||||
/// <exception cref="T:System.Runtime.Serialization.SerializationException">The exception could not be deserialized correctly.</exception>
|
||||
[SecurityCritical]
|
||||
protected AggregateException(SerializationInfo info, StreamingContext context) :
|
||||
base(info, context)
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
throw new ArgumentNullException("info");
|
||||
}
|
||||
|
||||
Exception[] innerExceptions = info.GetValue("InnerExceptions", typeof(Exception[])) as Exception[];
|
||||
if (innerExceptions == null)
|
||||
{
|
||||
throw new SerializationException(Environment.GetResourceString("AggregateException_DeserializationFailure"));
|
||||
}
|
||||
|
||||
m_innerExceptions = new ReadOnlyCollection<Exception>(innerExceptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> with information about
|
||||
/// the exception.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds
|
||||
/// the serialized object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that
|
||||
/// contains contextual information about the source or destination. </param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="info"/> argument is null.</exception>
|
||||
[SecurityCritical]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
throw new ArgumentNullException("info");
|
||||
}
|
||||
|
||||
base.GetObjectData(info, context);
|
||||
|
||||
Exception[] innerExceptions = new Exception[m_innerExceptions.Count];
|
||||
m_innerExceptions.CopyTo(innerExceptions, 0);
|
||||
info.AddValue("InnerExceptions", innerExceptions, typeof(Exception[]));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="System.AggregateException"/> that is the root cause of this exception.
|
||||
/// </summary>
|
||||
public override Exception GetBaseException()
|
||||
{
|
||||
// Returns the first inner AggregateException that contains more or less than one inner exception
|
||||
|
||||
// Recursively traverse the inner exceptions as long as the inner exception of type AggregateException and has only one inner exception
|
||||
Exception back = this;
|
||||
AggregateException backAsAggregate = this;
|
||||
while (backAsAggregate != null && backAsAggregate.InnerExceptions.Count == 1)
|
||||
{
|
||||
back = back.InnerException;
|
||||
backAsAggregate = back as AggregateException;
|
||||
}
|
||||
return back;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a read-only collection of the <see cref="T:System.Exception"/> instances that caused the
|
||||
/// current exception.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<Exception> InnerExceptions
|
||||
{
|
||||
get { return m_innerExceptions; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a handler on each <see cref="T:System.Exception"/> contained by this <see
|
||||
/// cref="AggregateException"/>.
|
||||
/// </summary>
|
||||
/// <param name="predicate">The predicate to execute for each exception. The predicate accepts as an
|
||||
/// argument the <see cref="T:System.Exception"/> to be processed and returns a Boolean to indicate
|
||||
/// whether the exception was handled.</param>
|
||||
/// <remarks>
|
||||
/// Each invocation of the <paramref name="predicate"/> returns true or false to indicate whether the
|
||||
/// <see cref="T:System.Exception"/> was handled. After all invocations, if any exceptions went
|
||||
/// unhandled, all unhandled exceptions will be put into a new <see cref="AggregateException"/>
|
||||
/// which will be thrown. Otherwise, the <see cref="Handle"/> method simply returns. If any
|
||||
/// invocations of the <paramref name="predicate"/> throws an exception, it will halt the processing
|
||||
/// of any more exceptions and immediately propagate the thrown exception as-is.
|
||||
/// </remarks>
|
||||
/// <exception cref="AggregateException">An exception contained by this <see
|
||||
/// cref="AggregateException"/> was not handled.</exception>
|
||||
/// <exception cref="T:System.ArgumentNullException">The <paramref name="predicate"/> argument is
|
||||
/// null.</exception>
|
||||
public void Handle(Func<Exception, bool> predicate)
|
||||
{
|
||||
if (predicate == null)
|
||||
{
|
||||
throw new ArgumentNullException("predicate");
|
||||
}
|
||||
|
||||
List<Exception> unhandledExceptions = null;
|
||||
for (int i = 0; i < m_innerExceptions.Count; i++)
|
||||
{
|
||||
// If the exception was not handled, lazily allocate a list of unhandled
|
||||
// exceptions (to be rethrown later) and add it.
|
||||
if (!predicate(m_innerExceptions[i]))
|
||||
{
|
||||
if (unhandledExceptions == null)
|
||||
{
|
||||
unhandledExceptions = new List<Exception>();
|
||||
}
|
||||
|
||||
unhandledExceptions.Add(m_innerExceptions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// If there are unhandled exceptions remaining, throw them.
|
||||
if (unhandledExceptions != null)
|
||||
{
|
||||
throw new AggregateException(Message, unhandledExceptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Flattens an <see cref="AggregateException"/> instances into a single, new instance.
|
||||
/// </summary>
|
||||
/// <returns>A new, flattened <see cref="AggregateException"/>.</returns>
|
||||
/// <remarks>
|
||||
/// If any inner exceptions are themselves instances of
|
||||
/// <see cref="AggregateException"/>, this method will recursively flatten all of them. The
|
||||
/// inner exceptions returned in the new <see cref="AggregateException"/>
|
||||
/// will be the union of all of the the inner exceptions from exception tree rooted at the provided
|
||||
/// <see cref="AggregateException"/> instance.
|
||||
/// </remarks>
|
||||
public AggregateException Flatten()
|
||||
{
|
||||
// Initialize a collection to contain the flattened exceptions.
|
||||
List<Exception> flattenedExceptions = new List<Exception>();
|
||||
|
||||
// Create a list to remember all aggregates to be flattened, this will be accessed like a FIFO queue
|
||||
List<AggregateException> exceptionsToFlatten = new List<AggregateException>();
|
||||
exceptionsToFlatten.Add(this);
|
||||
int nDequeueIndex = 0;
|
||||
|
||||
// Continue removing and recursively flattening exceptions, until there are no more.
|
||||
while (exceptionsToFlatten.Count > nDequeueIndex)
|
||||
{
|
||||
// dequeue one from exceptionsToFlatten
|
||||
IList<Exception> currentInnerExceptions = exceptionsToFlatten[nDequeueIndex++].InnerExceptions;
|
||||
|
||||
for (int i = 0; i < currentInnerExceptions.Count; i++)
|
||||
{
|
||||
Exception currentInnerException = currentInnerExceptions[i];
|
||||
|
||||
if (currentInnerException == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AggregateException currentInnerAsAggregate = currentInnerException as AggregateException;
|
||||
|
||||
// If this exception is an aggregate, keep it around for later. Otherwise,
|
||||
// simply add it to the list of flattened exceptions to be returned.
|
||||
if (currentInnerAsAggregate != null)
|
||||
{
|
||||
exceptionsToFlatten.Add(currentInnerAsAggregate);
|
||||
}
|
||||
else
|
||||
{
|
||||
flattenedExceptions.Add(currentInnerException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new AggregateException(Message, flattenedExceptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and returns a string representation of the current <see cref="AggregateException"/>.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of the current exception.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string text = base.ToString();
|
||||
|
||||
for (int i = 0; i < m_innerExceptions.Count; i++)
|
||||
{
|
||||
text = String.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
Environment.GetResourceString("AggregateException_ToString"),
|
||||
text, Environment.NewLine, i, m_innerExceptions[i].ToString(), "<---", Environment.NewLine);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This helper property is used by the DebuggerDisplay.
|
||||
///
|
||||
/// Note that we don't want to remove this property and change the debugger display to {InnerExceptions.Count}
|
||||
/// because DebuggerDisplay should be a single property access or parameterless method call, so that the debugger
|
||||
/// can use a fast path without using the expression evaluator.
|
||||
///
|
||||
/// See http://msdn.microsoft.com/en-us/library/x810d419.aspx
|
||||
/// </summary>
|
||||
private int InnerExceptionCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return InnerExceptions.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,173 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class AppContext
|
||||
{
|
||||
[Flags]
|
||||
private enum SwitchValueState
|
||||
{
|
||||
HasFalseValue = 0x1,
|
||||
HasTrueValue = 0x2,
|
||||
HasLookedForOverride = 0x4,
|
||||
UnknownValue = 0x8 // Has no default and could not find an override
|
||||
}
|
||||
private static Dictionary<string, SwitchValueState> s_switchMap = new Dictionary<string, SwitchValueState>();
|
||||
private static readonly object s_syncLock = new object();
|
||||
|
||||
public static string BaseDirectory
|
||||
{
|
||||
#if FEATURE_CORECLR
|
||||
[System.Security.SecuritySafeCritical]
|
||||
#endif
|
||||
get
|
||||
{
|
||||
// The value of APP_CONTEXT_BASE_DIRECTORY key has to be a string and it is not allowed to be any other type.
|
||||
// Otherwise the caller will get invalid cast exception
|
||||
return (string) AppDomain.CurrentDomain.GetData("APP_CONTEXT_BASE_DIRECTORY") ?? AppDomain.CurrentDomain.BaseDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
#region Switch APIs
|
||||
#if !MONO
|
||||
static AppContext()
|
||||
{
|
||||
// populate the AppContext with the default set of values
|
||||
AppContextDefaultValues.PopulateDefaultValues();
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Try to get the value of the switch.
|
||||
/// </summary>
|
||||
/// <param name="switchName">The name of the switch</param>
|
||||
/// <param name="isEnabled">A variable where to place the value of the switch</param>
|
||||
/// <returns>A return value of true represents that the switch was set and <paramref name="isEnabled"/> contains the value of the switch</returns>
|
||||
public static bool TryGetSwitch(string switchName, out bool isEnabled)
|
||||
{
|
||||
if (switchName == null)
|
||||
throw new ArgumentNullException("switchName");
|
||||
if (switchName.Length == 0)
|
||||
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "switchName");
|
||||
|
||||
// By default, the switch is not enabled.
|
||||
isEnabled = false;
|
||||
|
||||
SwitchValueState switchValue;
|
||||
lock (s_switchMap)
|
||||
{
|
||||
if (s_switchMap.TryGetValue(switchName, out switchValue))
|
||||
{
|
||||
// The value is in the dictionary.
|
||||
// There are 3 cases here:
|
||||
// 1. The value of the switch is 'unknown'. This means that the switch name is not known to the system (either via defaults or checking overrides).
|
||||
// Example: This is the case when, during a servicing event, a switch is added to System.Xml which ships before mscorlib. The value of the switch
|
||||
// Will be unknown to mscorlib.dll and we want to prevent checking the overrides every time we check this switch
|
||||
// 2. The switch has a valid value AND we have read the overrides for it
|
||||
// Example: TryGetSwitch is called for a switch set via SetSwitch
|
||||
// 3. The switch has the default value and we need to check for overrides
|
||||
// Example: TryGetSwitch is called for the first time for a switch that has a default value
|
||||
|
||||
// 1. The value is unknown
|
||||
if (switchValue == SwitchValueState.UnknownValue)
|
||||
{
|
||||
isEnabled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We get the value of isEnabled from the value that we stored in the dictionary
|
||||
isEnabled = (switchValue & SwitchValueState.HasTrueValue) == SwitchValueState.HasTrueValue;
|
||||
|
||||
// 2. The switch has a valid value AND we have checked for overrides
|
||||
if ((switchValue & SwitchValueState.HasLookedForOverride) == SwitchValueState.HasLookedForOverride)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#if !MONO
|
||||
// 3. The switch has a valid value, but we need to check for overrides.
|
||||
// Regardless of whether or not the switch has an override, we need to update the value to reflect
|
||||
// the fact that we checked for overrides.
|
||||
bool overrideValue;
|
||||
if (AppContextDefaultValues.TryGetSwitchOverride(switchName, out overrideValue))
|
||||
{
|
||||
// we found an override!
|
||||
isEnabled = overrideValue;
|
||||
}
|
||||
#endif
|
||||
// Update the switch in the dictionary to mark it as 'checked for override'
|
||||
s_switchMap[switchName] = (isEnabled ? SwitchValueState.HasTrueValue : SwitchValueState.HasFalseValue)
|
||||
| SwitchValueState.HasLookedForOverride;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The value is NOT in the dictionary
|
||||
// In this case we need to see if we have an override defined for the value.
|
||||
// There are 2 cases:
|
||||
// 1. The value has an override specified. In this case we need to add the value to the dictionary
|
||||
// and mark it as checked for overrides
|
||||
// Example: In a servicing event, System.Xml introduces a switch and an override is specified.
|
||||
// The value is not found in mscorlib (as System.Xml ships independent of mscorlib)
|
||||
// 2. The value does not have an override specified
|
||||
// In this case, we want to capture the fact that we looked for a value and found nothing by adding
|
||||
// an entry in the dictionary with the 'sentinel' value of 'SwitchValueState.UnknownValue'.
|
||||
// Example: This will prevent us from trying to find overrides for values that we don't have in the dictionary
|
||||
#if !MONO
|
||||
// 1. The value has an override specified.
|
||||
bool overrideValue;
|
||||
if (AppContextDefaultValues.TryGetSwitchOverride(switchName, out overrideValue))
|
||||
{
|
||||
isEnabled = overrideValue;
|
||||
|
||||
// Update the switch in the dictionary to mark it as 'checked for override'
|
||||
s_switchMap[switchName] = (isEnabled ? SwitchValueState.HasTrueValue : SwitchValueState.HasFalseValue)
|
||||
| SwitchValueState.HasLookedForOverride;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
// 2. The value does not have an override.
|
||||
s_switchMap[switchName] = SwitchValueState.UnknownValue;
|
||||
}
|
||||
}
|
||||
return false; // we did not find a value for the switch
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assign a switch a value
|
||||
/// </summary>
|
||||
/// <param name="switchName">The name of the switch</param>
|
||||
/// <param name="isEnabled">The value to assign</param>
|
||||
public static void SetSwitch(string switchName, bool isEnabled)
|
||||
{
|
||||
if (switchName == null)
|
||||
throw new ArgumentNullException("switchName");
|
||||
if (switchName.Length == 0)
|
||||
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "switchName");
|
||||
|
||||
lock (s_syncLock)
|
||||
{
|
||||
// Store the new value and the fact that we checked in the dictionary
|
||||
s_switchMap[switchName] = (isEnabled ? SwitchValueState.HasTrueValue : SwitchValueState.HasFalseValue)
|
||||
| SwitchValueState.HasLookedForOverride;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is going to be called from the AppContextDefaultValues class when setting up the
|
||||
/// default values for the switches. !!!! This method is called during the static constructor so it does not
|
||||
/// take a lock !!!! If you are planning to use this outside of that, please ensure proper locking.
|
||||
/// </summary>
|
||||
internal static void DefineSwitchDefault(string switchName, bool isEnabled)
|
||||
{
|
||||
s_switchMap[switchName] = isEnabled ? SwitchValueState.HasTrueValue : SwitchValueState.HasFalseValue;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
//
|
||||
// This file is used to provide an implementation for defining a default value
|
||||
// This should be compiled only in mscorlib where the AppContext class is available
|
||||
//
|
||||
|
||||
namespace System
|
||||
{
|
||||
internal static partial class AppContextDefaultValues
|
||||
{
|
||||
/// <summary>
|
||||
/// This method allows reading the override for a switch.
|
||||
/// The implementation is platform specific
|
||||
/// </summary>
|
||||
public static bool TryGetSwitchOverride(string switchName, out bool overrideValue)
|
||||
{
|
||||
// The default value for a switch is 'false'
|
||||
overrideValue = false;
|
||||
|
||||
// Read the override value
|
||||
bool overrideFound = false;
|
||||
|
||||
// This partial method will be removed if there are no implementations of it.
|
||||
TryGetSwitchOverridePartial(switchName, ref overrideFound, ref overrideValue);
|
||||
|
||||
return overrideFound;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
using System;
|
||||
|
||||
namespace System
|
||||
{
|
||||
internal static partial class AppContextDefaultValues
|
||||
{
|
||||
|
||||
internal static readonly string SwitchNoAsyncCurrentCulture = "Switch.System.Globalization.NoAsyncCurrentCulture";
|
||||
internal static readonly string SwitchThrowExceptionIfDisposedCancellationTokenSource = "Switch.System.Threading.ThrowExceptionIfDisposedCancellationTokenSource";
|
||||
internal static readonly string SwitchPreserveEventListnerObjectIdentity = "Switch.System.Diagnostics.EventSource.PreserveEventListnerObjectIdentity";
|
||||
|
||||
|
||||
// This is a partial method. Platforms can provide an implementation of it that will set override values
|
||||
// from whatever mechanism is available on that platform. If no implementation is provided, the compiler is going to remove the calls
|
||||
// to it from the code
|
||||
// We are going to have an implementation of this method for the Desktop platform that will read the overrides from app.config, registry and
|
||||
// the shim database. Additional implementation can be provided for other platforms.
|
||||
static partial void PopulateOverrideValuesPartial();
|
||||
|
||||
static partial void PopulateDefaultValuesPartial(string platformIdentifier, string profile, int version)
|
||||
{
|
||||
// When defining a new switch you should add it to the last known version.
|
||||
// For instance, if you are adding a switch in .NET 4.6 (the release after 4.5.2) you should defined your switch
|
||||
// like this:
|
||||
// if (version <= 40502) ...
|
||||
// This ensures that all previous versions of that platform (up-to 4.5.2) will get the old behavior by default
|
||||
// NOTE: When adding a default value for a switch please make sure that the default value is added to ALL of the existing platforms!
|
||||
// NOTE: When adding a new if statement for the version please ensure that ALL previous switches are enabled (ie. don't use else if)
|
||||
switch (platformIdentifier)
|
||||
{
|
||||
case ".NETCore":
|
||||
case ".NETFramework":
|
||||
{
|
||||
if (version <= 40502)
|
||||
{
|
||||
AppContext.DefineSwitchDefault(SwitchNoAsyncCurrentCulture, true);
|
||||
AppContext.DefineSwitchDefault(SwitchThrowExceptionIfDisposedCancellationTokenSource, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "WindowsPhone":
|
||||
case "WindowsPhoneApp":
|
||||
{
|
||||
if (version <= 80100)
|
||||
{
|
||||
AppContext.DefineSwitchDefault(SwitchNoAsyncCurrentCulture, true);
|
||||
AppContext.DefineSwitchDefault(SwitchThrowExceptionIfDisposedCancellationTokenSource, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we should read the overrides if any are defined
|
||||
PopulateOverrideValuesPartial();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,136 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Security;
|
||||
|
||||
namespace System
|
||||
{
|
||||
internal static partial class AppContextDefaultValues
|
||||
{
|
||||
/// <summary>
|
||||
/// This method is going to parse the <paramref name="overrides"/> parameter and set the values corresponding to them
|
||||
/// in the AppContext object
|
||||
/// </summary>
|
||||
[SecuritySafeCritical]
|
||||
static partial void PopulateOverrideValuesPartial()
|
||||
{
|
||||
// Retrieve the value from EE config.
|
||||
string overrides = System.Runtime.Versioning.CompatibilitySwitch.GetAppContextOverridesInternalCall();
|
||||
|
||||
// If we have no override values, do nothing.
|
||||
if (string.IsNullOrEmpty(overrides))
|
||||
return;
|
||||
|
||||
bool encounteredEquals = false, encounteredCharsInKey = false, encounteredCharsInValue = false;
|
||||
int previousSemicolonPos = -1, firstEqualsPos = -1;
|
||||
|
||||
// Iterate over the string one character at a time until we reach the end of the string.
|
||||
for (int currentPos = 0; currentPos <= overrides.Length; currentPos++)
|
||||
{
|
||||
// If the current position is either ';' or 'end-of-string' then we potentially have a key=value pair
|
||||
if (currentPos == overrides.Length || overrides[currentPos] == ';')
|
||||
{
|
||||
// We only have a key=value pair if we encountered an equals, characters in the key and in the value
|
||||
// portion of the pair.
|
||||
if (encounteredEquals && encounteredCharsInKey && encounteredCharsInValue)
|
||||
{
|
||||
// We compute the indexes in the string for key and value
|
||||
int firstCharOfKey = previousSemicolonPos + 1; //+1 because we don't take the ';' char
|
||||
int lenghtOfKey = firstEqualsPos - previousSemicolonPos - 1; //-1 because we don't take the '=' char
|
||||
string name = overrides.Substring(firstCharOfKey, lenghtOfKey);
|
||||
|
||||
int firstCharOfValue = firstEqualsPos + 1; // +1 because we don't count the '='
|
||||
int lengthOfValue = currentPos - firstEqualsPos - 1; // -1 because we don't count the '='
|
||||
string value = overrides.Substring(firstCharOfValue, lengthOfValue);
|
||||
|
||||
// apply the value only if it parses as a boolean
|
||||
bool switchValue;
|
||||
if (bool.TryParse(value, out switchValue))
|
||||
{
|
||||
// If multiple switches have the same name, the last value that we find will win.
|
||||
AppContext.SetSwitch(name, switchValue);
|
||||
}
|
||||
}
|
||||
previousSemicolonPos = currentPos;
|
||||
|
||||
// We need to reset these flags once we encounter a ';'
|
||||
encounteredCharsInKey = encounteredCharsInValue = encounteredEquals = false;
|
||||
}
|
||||
else if (overrides[currentPos] == '=')
|
||||
{
|
||||
// if the current character is '=' then we should flag it and remember it
|
||||
if (!encounteredEquals)
|
||||
{
|
||||
encounteredEquals = true;
|
||||
firstEqualsPos = currentPos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to know if the key or value contain any characters (other than ';' and '=');
|
||||
if (encounteredEquals)
|
||||
{
|
||||
encounteredCharsInValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
encounteredCharsInKey = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note -- partial methods cannot return a value so we use refs to return information
|
||||
[SecuritySafeCritical]
|
||||
static partial void TryGetSwitchOverridePartial(string switchName, ref bool overrideFound, ref bool overrideValue)
|
||||
{
|
||||
string valueFromConfig = null;
|
||||
bool boolFromConfig;
|
||||
overrideFound = false;
|
||||
|
||||
// Read the value from the registry if we can (ie. the key exists)
|
||||
if (s_switchesRegKey != null)
|
||||
{
|
||||
// try to read it from the registry key and return null if the switch name is not found
|
||||
valueFromConfig = s_switchesRegKey.GetValue(switchName, (string)null) as string;
|
||||
}
|
||||
|
||||
// Note: valueFromConfig will be null only if the key is not found.
|
||||
// Read the value from the Shim database.
|
||||
if (valueFromConfig == null)
|
||||
{
|
||||
// We are only going to check the Shim Database for an override in this case
|
||||
valueFromConfig = System.Runtime.Versioning.CompatibilitySwitch.GetValue(switchName);
|
||||
}
|
||||
|
||||
if (valueFromConfig != null && bool.TryParse(valueFromConfig, out boolFromConfig))
|
||||
{
|
||||
// If we found a valid override value, we need to let the caller know that.
|
||||
overrideValue = boolFromConfig;
|
||||
overrideFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Cached registry key used to read value overrides from the registry
|
||||
private static RegistryKey s_switchesRegKey = OpenRegKeyNoThrow();
|
||||
|
||||
/// <summary>
|
||||
/// Opens the registry key where the switches are stored and returns null if there is an issue opening the key
|
||||
/// </summary>
|
||||
private static RegistryKey OpenRegKeyNoThrow()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework\AppContext");
|
||||
}
|
||||
catch { return null; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,169 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace System
|
||||
{
|
||||
internal static partial class AppContextDefaultValues
|
||||
{
|
||||
public static void PopulateDefaultValues()
|
||||
{
|
||||
string platformIdentifier, profile;
|
||||
int version;
|
||||
|
||||
ParseTargetFrameworkName(out platformIdentifier, out profile, out version);
|
||||
|
||||
// Call into each library to populate their default switches
|
||||
PopulateDefaultValuesPartial(platformIdentifier, profile, version);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We have this separate method for getting the parsed elements out of the TargetFrameworkName so we can
|
||||
/// more easily support this on other platforms.
|
||||
/// </summary>
|
||||
private static void ParseTargetFrameworkName(out string identifier, out string profile, out int version)
|
||||
{
|
||||
string targetFrameworkMoniker = AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName;
|
||||
|
||||
// If we don't have a TFM then we should default to the 4.0 behavior where all quirks are turned on.
|
||||
if (!TryParseFrameworkName(targetFrameworkMoniker, out identifier, out version, out profile))
|
||||
{
|
||||
#if FEATURE_CORECLR
|
||||
if (CompatibilitySwitches.UseLatestBehaviorWhenTFMNotSpecified)
|
||||
{
|
||||
// If we want to use the latest behavior it is enough to set the value of the switch to string.Empty.
|
||||
// When the get to the caller of this method (PopulateDefaultValuesPartial) we are going to use the
|
||||
// identifier we just set to decide which switches to turn on. By having an empty string as the
|
||||
// identifier we are simply saying -- don't turn on any switches, and we are going to get the latest
|
||||
// behavior for all the switches
|
||||
identifier = string.Empty;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
identifier = ".NETFramework";
|
||||
version = 40000;
|
||||
profile = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This code was a constructor copied from the FrameworkName class, which is located in System.dll.
|
||||
// Parses strings in the following format: "<identifier>, Version=[v|V]<version>, Profile=<profile>"
|
||||
// - The identifier and version is required, profile is optional
|
||||
// - Only three components are allowed.
|
||||
// - The version string must be in the System.Version format; an optional "v" or "V" prefix is allowed
|
||||
private static bool TryParseFrameworkName(String frameworkName, out String identifier, out int version, out String profile)
|
||||
{
|
||||
// For parsing a target Framework moniker, from the FrameworkName class
|
||||
const char c_componentSeparator = ',';
|
||||
const char c_keyValueSeparator = '=';
|
||||
const char c_versionValuePrefix = 'v';
|
||||
const String c_versionKey = "Version";
|
||||
const String c_profileKey = "Profile";
|
||||
|
||||
identifier = profile = string.Empty;
|
||||
version = 0;
|
||||
|
||||
if (frameworkName == null || frameworkName.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] components = frameworkName.Split(c_componentSeparator);
|
||||
version = 0;
|
||||
|
||||
// Identifer and Version are required, Profile is optional.
|
||||
if (components.Length < 2 || components.Length > 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// 1) Parse the "Identifier", which must come first. Trim any whitespace
|
||||
//
|
||||
identifier = components[0].Trim();
|
||||
|
||||
if (identifier.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool versionFound = false;
|
||||
profile = null;
|
||||
|
||||
//
|
||||
// The required "Version" and optional "Profile" component can be in any order
|
||||
//
|
||||
for (int i = 1; i < components.Length; i++)
|
||||
{
|
||||
// Get the key/value pair separated by '='
|
||||
string[] keyValuePair = components[i].Split(c_keyValueSeparator);
|
||||
|
||||
if (keyValuePair.Length != 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the key and value, trimming any whitespace
|
||||
string key = keyValuePair[0].Trim();
|
||||
string value = keyValuePair[1].Trim();
|
||||
|
||||
//
|
||||
// 2) Parse the required "Version" key value
|
||||
//
|
||||
if (key.Equals(c_versionKey, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
versionFound = true;
|
||||
|
||||
// Allow the version to include a 'v' or 'V' prefix...
|
||||
if (value.Length > 0 && (value[0] == c_versionValuePrefix || value[0] == 'V'))
|
||||
{
|
||||
value = value.Substring(1);
|
||||
}
|
||||
Version realVersion = new Version(value);
|
||||
// The version class will represent some unset values as -1 internally (instead of 0).
|
||||
version = realVersion.Major * 10000;
|
||||
if (realVersion.Minor > 0)
|
||||
version += realVersion.Minor * 100;
|
||||
if (realVersion.Build > 0)
|
||||
version += realVersion.Build;
|
||||
}
|
||||
//
|
||||
// 3) Parse the optional "Profile" key value
|
||||
//
|
||||
else if (key.Equals(c_profileKey, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!String.IsNullOrEmpty(value))
|
||||
{
|
||||
profile = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!versionFound)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is a partial method. Platforms (such as Desktop) can provide an implementation of it that will read override value
|
||||
// from whatever mechanism is available on that platform. If no implementation is provided, the compiler is going to remove the calls
|
||||
// to it from the code
|
||||
static partial void TryGetSwitchOverridePartial(string switchName, ref bool overrideFound, ref bool overrideValue);
|
||||
|
||||
/// This is a partial method. This method is responsible for populating the default values based on a TFM.
|
||||
/// It is partial because each library should define this method in their code to contain their defaults.
|
||||
static partial void PopulateDefaultValuesPartial(string platformIdentifier, string profile, int version);
|
||||
}
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
namespace System
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
internal static class AppContextSwitches
|
||||
{
|
||||
private static int _noAsyncCurrentCulture;
|
||||
public static bool NoAsyncCurrentCulture
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return GetCachedSwitchValue(AppContextDefaultValues.SwitchNoAsyncCurrentCulture, ref _noAsyncCurrentCulture);
|
||||
}
|
||||
}
|
||||
|
||||
private static int _throwExceptionIfDisposedCancellationTokenSource;
|
||||
public static bool ThrowExceptionIfDisposedCancellationTokenSource
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return GetCachedSwitchValue(AppContextDefaultValues.SwitchThrowExceptionIfDisposedCancellationTokenSource, ref _throwExceptionIfDisposedCancellationTokenSource);
|
||||
}
|
||||
}
|
||||
|
||||
private static int _preserveEventListnerObjectIdentity;
|
||||
public static bool PreserveEventListnerObjectIdentity
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return GetCachedSwitchValue(AppContextDefaultValues.SwitchPreserveEventListnerObjectIdentity, ref _preserveEventListnerObjectIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Implementation details
|
||||
//
|
||||
|
||||
private static bool DisableCaching { get; set; }
|
||||
|
||||
static AppContextSwitches()
|
||||
{
|
||||
bool isEnabled;
|
||||
if (AppContext.TryGetSwitch(@"TestSwitch.LocalAppContext.DisableCaching", out isEnabled))
|
||||
{
|
||||
DisableCaching = isEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static bool GetCachedSwitchValue(string switchName, ref int switchValue)
|
||||
{
|
||||
if (switchValue < 0) return false;
|
||||
if (switchValue > 0) return true;
|
||||
|
||||
return GetCachedSwitchValueInternal(switchName, ref switchValue);
|
||||
}
|
||||
|
||||
private static bool GetCachedSwitchValueInternal(string switchName, ref int switchValue)
|
||||
{
|
||||
bool isSwitchEnabled;
|
||||
AppContext.TryGetSwitch(switchName, out isSwitchEnabled);
|
||||
|
||||
if (DisableCaching)
|
||||
{
|
||||
return isSwitchEnabled;
|
||||
}
|
||||
|
||||
switchValue = isSwitchEnabled ? 1 /*true*/ : -1 /*false*/;
|
||||
return isSwitchEnabled;
|
||||
}
|
||||
}
|
||||
}
|
1431
mcs/class/referencesource/mscorlib/system/AppDomainSetup.cs
Normal file
1431
mcs/class/referencesource/mscorlib/system/AppDomainSetup.cs
Normal file
File diff suppressed because it is too large
Load Diff
42
mcs/class/referencesource/mscorlib/system/CLRConfig.cs
Normal file
42
mcs/class/referencesource/mscorlib/system/CLRConfig.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
///------------------------------------------------------------------------------
|
||||
/// <copyright file="CLRConfig.cs" company="Microsoft">
|
||||
/// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
/// </copyright>
|
||||
///
|
||||
/// <owner>gpaperin</owner>
|
||||
///------------------------------------------------------------------------------
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace System {
|
||||
|
||||
/// <summary>
|
||||
/// For now, this class should be the central point to collect all managed declarations
|
||||
/// of native functions designed to expose config switches.
|
||||
/// In Dev11 M2.2 we will redesign this class to expose CLRConfig from within the CLR
|
||||
/// and refactor managed Fx code to access all compat switches through here.
|
||||
/// </summary>
|
||||
[FriendAccessAllowed]
|
||||
internal class CLRConfig {
|
||||
|
||||
[FriendAccessAllowed]
|
||||
[System.Security.SecurityCritical]
|
||||
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal static extern bool CheckLegacyManagedDeflateStream();
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal static extern bool CheckThrowUnobservedTaskExceptions();
|
||||
|
||||
} // internal class CLRConfig
|
||||
|
||||
} // namespace System
|
||||
|
||||
// file CLRConfig
|
@@ -0,0 +1,82 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: FormattableString
|
||||
**
|
||||
**
|
||||
** Purpose: implementation of the FormattableString
|
||||
** class.
|
||||
**
|
||||
===========================================================*/
|
||||
namespace System
|
||||
{
|
||||
/// <summary>
|
||||
/// A composite format string along with the arguments to be formatted. An instance of this
|
||||
/// type may result from the use of the C# or VB language primitive "interpolated string".
|
||||
/// </summary>
|
||||
public abstract class FormattableString : IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// The composite format string.
|
||||
/// </summary>
|
||||
public abstract string Format { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns an object array that contains zero or more objects to format. Clients should not
|
||||
/// mutate the contents of the array.
|
||||
/// </summary>
|
||||
public abstract object[] GetArguments();
|
||||
|
||||
/// <summary>
|
||||
/// The number of arguments to be formatted.
|
||||
/// </summary>
|
||||
public abstract int ArgumentCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns one argument to be formatted from argument position <paramref name="index"/>.
|
||||
/// </summary>
|
||||
public abstract object GetArgument(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Format to a string using the given culture.
|
||||
/// </summary>
|
||||
public abstract string ToString(IFormatProvider formatProvider);
|
||||
|
||||
string IFormattable.ToString(string ignored, IFormatProvider formatProvider)
|
||||
{
|
||||
return ToString(formatProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format the given object in the invariant culture. This static method may be
|
||||
/// imported in C# by
|
||||
/// <code>
|
||||
/// using static System.FormattableString;
|
||||
/// </code>.
|
||||
/// Within the scope
|
||||
/// of that import directive an interpolated string may be formatted in the
|
||||
/// invariant culture by writing, for example,
|
||||
/// <code>
|
||||
/// Invariant($"{{ lat = {latitude}; lon = {longitude} }}")
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static string Invariant(FormattableString formattable)
|
||||
{
|
||||
if (formattable == null)
|
||||
{
|
||||
throw new ArgumentNullException("formattable");
|
||||
}
|
||||
|
||||
return formattable.ToString(Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(Globalization.CultureInfo.CurrentCulture);
|
||||
}
|
||||
}
|
||||
}
|
507
mcs/class/referencesource/mscorlib/system/Lazy.cs
Normal file
507
mcs/class/referencesource/mscorlib/system/Lazy.cs
Normal file
File diff suppressed because it is too large
Load Diff
208
mcs/class/referencesource/mscorlib/system/__comobject.cs
Normal file
208
mcs/class/referencesource/mscorlib/system/__comobject.cs
Normal file
@@ -0,0 +1,208 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: __ComObject
|
||||
**
|
||||
**
|
||||
** __ComObject is the root class for all COM wrappers. This class
|
||||
** defines only the basics. This class is used for wrapping COM objects
|
||||
** accessed from COM+
|
||||
**
|
||||
**
|
||||
===========================================================*/
|
||||
namespace System {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Reflection;
|
||||
using System.Security.Permissions;
|
||||
|
||||
internal class __ComObject : MarshalByRefObject
|
||||
{
|
||||
private Hashtable m_ObjectToDataMap;
|
||||
|
||||
/*============================================================
|
||||
** default constructor
|
||||
** can't instantiate this directly
|
||||
=============================================================*/
|
||||
protected __ComObject ()
|
||||
{
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// Overrides ToString() to make sure we call to IStringable if the
|
||||
// COM object implements it in the case of weakly typed RCWs
|
||||
//====================================================================
|
||||
public override string ToString()
|
||||
{
|
||||
//
|
||||
// Only do the IStringable cast when running under AppX for better compat
|
||||
// Otherwise we could do a IStringable cast in classic apps which could introduce
|
||||
// a thread transition which would lead to deadlock
|
||||
//
|
||||
if (AppDomain.IsAppXModel())
|
||||
{
|
||||
// Check whether the type implements IStringable.
|
||||
IStringable stringableType = this as IStringable;
|
||||
if (stringableType != null)
|
||||
{
|
||||
return stringableType.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return base.ToString();
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
internal IntPtr GetIUnknown(out bool fIsURTAggregated)
|
||||
{
|
||||
fIsURTAggregated = !GetType().IsDefined(typeof(ComImportAttribute), false);
|
||||
return System.Runtime.InteropServices.Marshal.GetIUnknownForObject(this);
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// This method retrieves the data associated with the specified
|
||||
// key if any such data exists for the current __ComObject.
|
||||
//====================================================================
|
||||
internal Object GetData(Object key)
|
||||
{
|
||||
Object data = null;
|
||||
|
||||
// Synchronize access to the map.
|
||||
lock(this)
|
||||
{
|
||||
// If the map hasn't been allocated, then there can be no data for the specified key.
|
||||
if (m_ObjectToDataMap != null)
|
||||
{
|
||||
// Look up the data in the map.
|
||||
data = m_ObjectToDataMap[key];
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// This method sets the data for the specified key on the current
|
||||
// __ComObject.
|
||||
//====================================================================
|
||||
internal bool SetData(Object key, Object data)
|
||||
{
|
||||
bool bAdded = false;
|
||||
|
||||
// Synchronize access to the map.
|
||||
lock(this)
|
||||
{
|
||||
// If the map hasn't been allocated yet, allocate it.
|
||||
if (m_ObjectToDataMap == null)
|
||||
m_ObjectToDataMap = new Hashtable();
|
||||
|
||||
// If there isn't already data in the map then add it.
|
||||
if (m_ObjectToDataMap[key] == null)
|
||||
{
|
||||
m_ObjectToDataMap[key] = data;
|
||||
bAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return bAdded;
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// This method is called from within the EE and releases all the
|
||||
// cached data for the __ComObject.
|
||||
//====================================================================
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
internal void ReleaseAllData()
|
||||
{
|
||||
// Synchronize access to the map.
|
||||
lock(this)
|
||||
{
|
||||
|
||||
// If the map hasn't been allocated, then there is nothing to do.
|
||||
if (m_ObjectToDataMap != null)
|
||||
{
|
||||
foreach (Object o in m_ObjectToDataMap.Values)
|
||||
{
|
||||
// Note: the value could be an object[]
|
||||
// We are fine for now as object[] doesn't implement IDisposable nor derive from __ComObject
|
||||
|
||||
// If the object implements IDisposable, then call Dispose on it.
|
||||
IDisposable DisposableObj = o as IDisposable;
|
||||
if (DisposableObj != null)
|
||||
DisposableObj.Dispose();
|
||||
|
||||
// If the object is a derived from __ComObject, then call Marshal.ReleaseComObject on it.
|
||||
__ComObject ComObj = o as __ComObject;
|
||||
if (ComObj != null)
|
||||
Marshal.ReleaseComObject(ComObj);
|
||||
}
|
||||
|
||||
// Set the map to null to indicate it has been cleaned up.
|
||||
m_ObjectToDataMap = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// This method is called from within the EE and is used to handle
|
||||
// calls on methods of event interfaces.
|
||||
//====================================================================
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
internal Object GetEventProvider(RuntimeType t)
|
||||
{
|
||||
// Check to see if we already have a cached event provider for this type.
|
||||
Object EvProvider = GetData(t);
|
||||
|
||||
// If we don't then we need to create one.
|
||||
if (EvProvider == null)
|
||||
EvProvider = CreateEventProvider(t);
|
||||
|
||||
return EvProvider;
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
internal int ReleaseSelf()
|
||||
{
|
||||
return Marshal.InternalReleaseComObject(this);
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
internal void FinalReleaseSelf()
|
||||
{
|
||||
Marshal.InternalFinalReleaseComObject(this);
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
#if !FEATURE_CORECLR
|
||||
[ReflectionPermissionAttribute(SecurityAction.Assert, MemberAccess=true)]
|
||||
#endif
|
||||
private Object CreateEventProvider(RuntimeType t)
|
||||
{
|
||||
// Create the event provider for the specified type.
|
||||
Object EvProvider = Activator.CreateInstance(t, Activator.ConstructorDefault | BindingFlags.NonPublic, null, new Object[]{this}, null);
|
||||
|
||||
// Attempt to cache the wrapper on the object.
|
||||
if (!SetData(t, EvProvider))
|
||||
{
|
||||
// Dispose the event provider if it implements IDisposable.
|
||||
IDisposable DisposableEvProv = EvProvider as IDisposable;
|
||||
if (DisposableEvProv != null)
|
||||
DisposableEvProv.Dispose();
|
||||
|
||||
// Another thead already cached the wrapper so use that one instead.
|
||||
EvProvider = GetData(t);
|
||||
}
|
||||
|
||||
return EvProvider;
|
||||
}
|
||||
}
|
||||
}
|
157
mcs/class/referencesource/mscorlib/system/__filters.cs
Normal file
157
mcs/class/referencesource/mscorlib/system/__filters.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
// __Filters.cs
|
||||
//
|
||||
// This class defines the delegate methods for the COM+ implemented filters.
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
namespace System {
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Globalization;
|
||||
[Serializable]
|
||||
internal class __Filters {
|
||||
|
||||
// Filters...
|
||||
// The following are the built in filters defined for this class. These
|
||||
// should really be defined as static methods. They are used in as delegates
|
||||
// which currently doesn't support static methods. We will change this
|
||||
// once the compiler supports delegates.
|
||||
//
|
||||
// Note that it is not possible to make this class static as suggested by
|
||||
// the above comment anymore because of it got marked serializable.
|
||||
|
||||
internal static readonly __Filters Instance = new __Filters();
|
||||
|
||||
// FilterAttribute
|
||||
// This method will search for a member based upon the attribute passed in.
|
||||
// filterCriteria -- an Int32 representing the attribute
|
||||
internal virtual bool FilterAttribute(MemberInfo m,Object filterCriteria)
|
||||
{
|
||||
// Check that the criteria object is an Integer object
|
||||
if (filterCriteria == null)
|
||||
throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt"));
|
||||
|
||||
switch (m.MemberType)
|
||||
{
|
||||
case MemberTypes.Constructor:
|
||||
case MemberTypes.Method: {
|
||||
|
||||
MethodAttributes criteria = 0;
|
||||
try {
|
||||
int i = (int) filterCriteria;
|
||||
criteria = (MethodAttributes) i;
|
||||
}
|
||||
catch {
|
||||
throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt"));
|
||||
}
|
||||
|
||||
|
||||
MethodAttributes attr;
|
||||
if (m.MemberType == MemberTypes.Method)
|
||||
attr = ((MethodInfo) m).Attributes;
|
||||
else
|
||||
attr = ((ConstructorInfo) m).Attributes;
|
||||
|
||||
if (((criteria & MethodAttributes.MemberAccessMask) != 0) && (attr & MethodAttributes.MemberAccessMask) != (criteria & MethodAttributes.MemberAccessMask))
|
||||
return false;
|
||||
if (((criteria & MethodAttributes.Static) != 0) && (attr & MethodAttributes.Static) == 0)
|
||||
return false;
|
||||
if (((criteria & MethodAttributes.Final) != 0) && (attr & MethodAttributes.Final) == 0)
|
||||
return false;
|
||||
if (((criteria & MethodAttributes.Virtual) != 0) && (attr & MethodAttributes.Virtual) == 0)
|
||||
return false;
|
||||
if (((criteria & MethodAttributes.Abstract) != 0) && (attr & MethodAttributes.Abstract) == 0)
|
||||
return false;
|
||||
if (((criteria & MethodAttributes.SpecialName) != 0) && (attr & MethodAttributes.SpecialName) == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
case MemberTypes.Field:
|
||||
{
|
||||
FieldAttributes criteria = 0;
|
||||
try {
|
||||
int i = (int) filterCriteria;
|
||||
criteria = (FieldAttributes) i;
|
||||
}
|
||||
catch {
|
||||
throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt"));
|
||||
}
|
||||
|
||||
FieldAttributes attr = ((FieldInfo) m).Attributes;
|
||||
if (((criteria & FieldAttributes.FieldAccessMask) != 0) && (attr & FieldAttributes.FieldAccessMask) != (criteria & FieldAttributes.FieldAccessMask))
|
||||
return false;
|
||||
if (((criteria & FieldAttributes.Static) != 0) && (attr & FieldAttributes.Static) == 0)
|
||||
return false;
|
||||
if (((criteria & FieldAttributes.InitOnly) != 0) && (attr & FieldAttributes.InitOnly) == 0)
|
||||
return false;
|
||||
if (((criteria & FieldAttributes.Literal) != 0) && (attr & FieldAttributes.Literal) == 0)
|
||||
return false;
|
||||
if (((criteria & FieldAttributes.NotSerialized) != 0) && (attr & FieldAttributes.NotSerialized) == 0)
|
||||
return false;
|
||||
if (((criteria & FieldAttributes.PinvokeImpl) != 0) && (attr & FieldAttributes.PinvokeImpl) == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// FilterName
|
||||
// This method will filter based upon the name. A partial wildcard
|
||||
// at the end of the string is supported.
|
||||
// filterCriteria -- This is the string name
|
||||
internal virtual bool FilterName(MemberInfo m,Object filterCriteria)
|
||||
{
|
||||
// Check that the criteria object is a String object
|
||||
if(filterCriteria == null || !(filterCriteria is String))
|
||||
throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritString"));
|
||||
|
||||
// At the moment this fails if its done on a single line....
|
||||
String str = ((String) filterCriteria);
|
||||
str = str.Trim();
|
||||
|
||||
String name = m.Name;
|
||||
// Get the nested class name only, as opposed to the mangled one
|
||||
if (m.MemberType == MemberTypes.NestedType)
|
||||
name = name.Substring(name.LastIndexOf('+') + 1);
|
||||
// Check to see if this is a prefix or exact match requirement
|
||||
if (str.Length > 0 && str[str.Length - 1] == '*') {
|
||||
str = str.Substring(0, str.Length - 1);
|
||||
return (name.StartsWith(str, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
return (name.Equals(str));
|
||||
}
|
||||
|
||||
// FilterIgnoreCase
|
||||
// This delegate will do a name search but does it with the
|
||||
// ignore case specified.
|
||||
internal virtual bool FilterIgnoreCase(MemberInfo m,Object filterCriteria)
|
||||
{
|
||||
// Check that the criteria object is a String object
|
||||
if(filterCriteria == null || !(filterCriteria is String))
|
||||
throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritString"));
|
||||
|
||||
String str = (String) filterCriteria;
|
||||
str = str.Trim();
|
||||
|
||||
String name = m.Name;
|
||||
// Get the nested class name only, as opposed to the mangled one
|
||||
if (m.MemberType == MemberTypes.NestedType)
|
||||
name = name.Substring(name.LastIndexOf('+') + 1);
|
||||
// Check to see if this is a prefix or exact match requirement
|
||||
if (str.Length > 0 && str[str.Length - 1] == '*') {
|
||||
str = str.Substring(0, str.Length - 1);
|
||||
return (String.Compare(name,0,str,0,str.Length,StringComparison.OrdinalIgnoreCase)==0);
|
||||
}
|
||||
|
||||
return (String.Compare(str,name, StringComparison.OrdinalIgnoreCase) == 0);
|
||||
}
|
||||
}
|
||||
}
|
132
mcs/class/referencesource/mscorlib/system/__hresults.cs
Normal file
132
mcs/class/referencesource/mscorlib/system/__hresults.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
//=============================================================================
|
||||
//
|
||||
// Class: __HResults
|
||||
//
|
||||
// Purpose: Define HResult constants. Every exception has one of these.
|
||||
//
|
||||
// Date: 98/08/31 11:57:11 AM
|
||||
//
|
||||
//===========================================================================*/
|
||||
namespace System {
|
||||
// Note: FACILITY_URT is defined as 0x13 (0x8013xxxx). Within that
|
||||
// range, 0x1yyy is for Runtime errors (used for Security, Metadata, etc).
|
||||
// In that subrange, 0x15zz and 0x16zz have been allocated for classlib-type
|
||||
// HResults. Also note that some of our HResults have to map to certain
|
||||
// COM HR's, etc.
|
||||
|
||||
// Another arbitrary decision... Feel free to change this, as long as you
|
||||
// renumber the HResults yourself (and update rexcep.h).
|
||||
// Reflection will use 0x1600 -> 0x161f. IO will use 0x1620 -> 0x163f.
|
||||
// Security will use 0x1640 -> 0x165f
|
||||
|
||||
// There are __HResults files in the IO, Remoting, Reflection &
|
||||
// Security/Util directories as well, so choose your HResults carefully.
|
||||
|
||||
using System;
|
||||
internal static class __HResults
|
||||
{
|
||||
|
||||
internal const int RO_E_CLOSED = unchecked((int)0x80000013);
|
||||
internal const int E_BOUNDS = unchecked((int)0x8000000B);
|
||||
internal const int E_CHANGED_STATE = unchecked((int)0x8000000C);
|
||||
internal const int E_FAIL = unchecked((int)0x80004005);
|
||||
internal const int E_POINTER = unchecked((int)0x80004003);
|
||||
internal const int E_NOTIMPL = unchecked((int)0x80004001);
|
||||
internal const int REGDB_E_CLASSNOTREG = unchecked((int)0x80040154);
|
||||
internal const int COR_E_AMBIGUOUSMATCH = unchecked((int)0x8000211D);
|
||||
internal const int COR_E_APPDOMAINUNLOADED = unchecked((int)0x80131014);
|
||||
internal const int COR_E_APPLICATION = unchecked((int)0x80131600);
|
||||
internal const int COR_E_ARGUMENT = unchecked((int)0x80070057);
|
||||
internal const int COR_E_ARGUMENTOUTOFRANGE = unchecked((int)0x80131502);
|
||||
internal const int COR_E_ARITHMETIC = unchecked((int)0x80070216);
|
||||
internal const int COR_E_ARRAYTYPEMISMATCH = unchecked((int)0x80131503);
|
||||
internal const int COR_E_BADIMAGEFORMAT = unchecked((int)0x8007000B);
|
||||
internal const int COR_E_TYPEUNLOADED = unchecked((int)0x80131013);
|
||||
internal const int COR_E_CANNOTUNLOADAPPDOMAIN = unchecked((int)0x80131015);
|
||||
internal const int COR_E_COMEMULATE = unchecked((int)0x80131535);
|
||||
internal const int COR_E_CONTEXTMARSHAL = unchecked((int)0x80131504);
|
||||
internal const int COR_E_DATAMISALIGNED = unchecked((int)0x80131541);
|
||||
internal const int COR_E_TIMEOUT = unchecked((int)0x80131505);
|
||||
internal const int COR_E_CUSTOMATTRIBUTEFORMAT = unchecked((int)0x80131605);
|
||||
internal const int COR_E_DIVIDEBYZERO = unchecked((int)0x80020012); // DISP_E_DIVBYZERO
|
||||
internal const int COR_E_DUPLICATEWAITOBJECT = unchecked((int)0x80131529);
|
||||
internal const int COR_E_EXCEPTION = unchecked((int)0x80131500);
|
||||
internal const int COR_E_EXECUTIONENGINE = unchecked((int)0x80131506);
|
||||
internal const int COR_E_FIELDACCESS = unchecked((int)0x80131507);
|
||||
internal const int COR_E_FORMAT = unchecked((int)0x80131537);
|
||||
internal const int COR_E_INDEXOUTOFRANGE = unchecked((int)0x80131508);
|
||||
internal const int COR_E_INSUFFICIENTMEMORY = unchecked((int)0x8013153D);
|
||||
internal const int COR_E_INSUFFICIENTEXECUTIONSTACK = unchecked((int)0x80131578);
|
||||
internal const int COR_E_INVALIDCAST = unchecked((int)0x80004002);
|
||||
internal const int COR_E_INVALIDCOMOBJECT = unchecked((int)0x80131527);
|
||||
internal const int COR_E_INVALIDFILTERCRITERIA = unchecked((int)0x80131601);
|
||||
internal const int COR_E_INVALIDOLEVARIANTTYPE = unchecked((int)0x80131531);
|
||||
internal const int COR_E_INVALIDOPERATION = unchecked((int)0x80131509);
|
||||
internal const int COR_E_INVALIDPROGRAM = unchecked((int)0x8013153A);
|
||||
internal const int COR_E_KEYNOTFOUND = unchecked((int)0x80131577);
|
||||
internal const int COR_E_MARSHALDIRECTIVE = unchecked((int)0x80131535);
|
||||
internal const int COR_E_MEMBERACCESS = unchecked((int)0x8013151A);
|
||||
internal const int COR_E_METHODACCESS = unchecked((int)0x80131510);
|
||||
internal const int COR_E_MISSINGFIELD = unchecked((int)0x80131511);
|
||||
internal const int COR_E_MISSINGMANIFESTRESOURCE = unchecked((int)0x80131532);
|
||||
internal const int COR_E_MISSINGMEMBER = unchecked((int)0x80131512);
|
||||
internal const int COR_E_MISSINGMETHOD = unchecked((int)0x80131513);
|
||||
internal const int COR_E_MISSINGSATELLITEASSEMBLY = unchecked((int)0x80131536);
|
||||
internal const int COR_E_MULTICASTNOTSUPPORTED = unchecked((int)0x80131514);
|
||||
internal const int COR_E_NOTFINITENUMBER = unchecked((int)0x80131528);
|
||||
internal const int COR_E_PLATFORMNOTSUPPORTED = unchecked((int)0x80131539);
|
||||
internal const int COR_E_NOTSUPPORTED = unchecked((int)0x80131515);
|
||||
internal const int COR_E_NULLREFERENCE = unchecked((int)0x80004003);
|
||||
internal const int COR_E_OBJECTDISPOSED = unchecked((int)0x80131622);
|
||||
internal const int COR_E_OPERATIONCANCELED = unchecked((int)0x8013153B);
|
||||
internal const int COR_E_OUTOFMEMORY = unchecked((int)0x8007000E);
|
||||
internal const int COR_E_OVERFLOW = unchecked((int)0x80131516);
|
||||
internal const int COR_E_RANK = unchecked((int)0x80131517);
|
||||
internal const int COR_E_REFLECTIONTYPELOAD = unchecked((int)0x80131602);
|
||||
internal const int COR_E_RUNTIMEWRAPPED = unchecked((int)0x8013153E);
|
||||
internal const int COR_E_SAFEARRAYRANKMISMATCH = unchecked((int)0x80131538);
|
||||
internal const int COR_E_SAFEARRAYTYPEMISMATCH = unchecked((int)0x80131533);
|
||||
internal const int COR_E_SAFEHANDLEMISSINGATTRIBUTE = unchecked((int)0x80131623);
|
||||
internal const int COR_E_SECURITY = unchecked((int)0x8013150A);
|
||||
internal const int COR_E_SERIALIZATION = unchecked((int)0x8013150C);
|
||||
internal const int COR_E_SEMAPHOREFULL = unchecked((int)0x8013152B);
|
||||
internal const int COR_E_WAITHANDLECANNOTBEOPENED = unchecked((int)0x8013152C);
|
||||
internal const int COR_E_ABANDONEDMUTEX = unchecked((int)0x8013152D);
|
||||
internal const int COR_E_STACKOVERFLOW = unchecked((int)0x800703E9);
|
||||
internal const int COR_E_SYNCHRONIZATIONLOCK = unchecked((int)0x80131518);
|
||||
internal const int COR_E_SYSTEM = unchecked((int)0x80131501);
|
||||
internal const int COR_E_TARGET = unchecked((int)0x80131603);
|
||||
internal const int COR_E_TARGETINVOCATION = unchecked((int)0x80131604);
|
||||
internal const int COR_E_TARGETPARAMCOUNT = unchecked((int)0x8002000e);
|
||||
internal const int COR_E_THREADABORTED = unchecked((int)0x80131530);
|
||||
internal const int COR_E_THREADINTERRUPTED = unchecked((int)0x80131519);
|
||||
internal const int COR_E_THREADSTATE = unchecked((int)0x80131520);
|
||||
internal const int COR_E_THREADSTOP = unchecked((int)0x80131521);
|
||||
internal const int COR_E_THREADSTART = unchecked((int)0x80131525);
|
||||
internal const int COR_E_TYPEACCESS = unchecked((int)0x80131543);
|
||||
internal const int COR_E_TYPEINITIALIZATION = unchecked((int)0x80131534);
|
||||
internal const int COR_E_TYPELOAD = unchecked((int)0x80131522);
|
||||
internal const int COR_E_ENTRYPOINTNOTFOUND = unchecked((int)0x80131523);
|
||||
internal const int COR_E_DLLNOTFOUND = unchecked((int)0x80131524);
|
||||
internal const int COR_E_UNAUTHORIZEDACCESS = unchecked((int)0x80070005);
|
||||
internal const int COR_E_UNSUPPORTEDFORMAT = unchecked((int)0x80131523);
|
||||
internal const int COR_E_VERIFICATION = unchecked((int)0x8013150D);
|
||||
internal const int COR_E_HOSTPROTECTION = unchecked((int)0x80131640);
|
||||
internal const int CORSEC_E_MIN_GRANT_FAIL = unchecked((int)0x80131417);
|
||||
internal const int CORSEC_E_NO_EXEC_PERM = unchecked((int)0x80131418);
|
||||
internal const int CORSEC_E_POLICY_EXCEPTION = unchecked((int)0x80131416);
|
||||
internal const int CORSEC_E_XMLSYNTAX = unchecked((int)0x80131418);
|
||||
internal const int NTE_FAIL = unchecked((int)0x80090020);
|
||||
internal const int CORSEC_E_CRYPTO = unchecked((int)0x80131430);
|
||||
internal const int CORSEC_E_CRYPTO_UNEX_OPER = unchecked((int)0x80131431);
|
||||
internal const int DISP_E_OVERFLOW = unchecked((int)0x8002000a);
|
||||
internal const int FUSION_E_REF_DEF_MISMATCH = unchecked((int)0x80131040);
|
||||
internal const int FUSION_E_INVALID_NAME = unchecked((int)0x80131047);
|
||||
internal const int TYPE_E_TYPEMISMATCH = unchecked((int)0x80028ca0);
|
||||
}
|
||||
}
|
246
mcs/class/referencesource/mscorlib/system/_localdatastore.cs
Normal file
246
mcs/class/referencesource/mscorlib/system/_localdatastore.cs
Normal file
@@ -0,0 +1,246 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*=============================================================================
|
||||
**
|
||||
** Class: LocalDataStore
|
||||
**
|
||||
**
|
||||
** Purpose: Class that stores local data. This class is used in cooperation
|
||||
** with the _LocalDataStoreMgr class.
|
||||
**
|
||||
**
|
||||
=============================================================================*/
|
||||
|
||||
namespace System {
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
// Helper class to aid removal of LocalDataStore from the LocalDataStoreMgr
|
||||
// LocalDataStoreMgr does not holds references to LocalDataStoreHolder. It holds
|
||||
// references to LocalDataStore only. LocalDataStoreHolder finalizer will run once
|
||||
// the only outstanding reference to the store is in LocalDataStoreMgr.
|
||||
sealed internal class LocalDataStoreHolder
|
||||
{
|
||||
private LocalDataStore m_Store;
|
||||
|
||||
public LocalDataStoreHolder(LocalDataStore store)
|
||||
{
|
||||
m_Store = store;
|
||||
}
|
||||
|
||||
~LocalDataStoreHolder()
|
||||
{
|
||||
LocalDataStore store = m_Store;
|
||||
if (store == null)
|
||||
return;
|
||||
|
||||
store.Dispose();
|
||||
}
|
||||
|
||||
public LocalDataStore Store
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Store;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed internal class LocalDataStoreElement
|
||||
{
|
||||
private Object m_value;
|
||||
private long m_cookie; // This is immutable cookie of the slot used to verify that
|
||||
// the value is indeed indeed owned by the slot. Necessary
|
||||
// to avoid resurection holes.
|
||||
|
||||
public LocalDataStoreElement(long cookie)
|
||||
{
|
||||
m_cookie = cookie;
|
||||
}
|
||||
|
||||
public Object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public long Cookie
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_cookie;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This class will not be marked serializable
|
||||
sealed internal class LocalDataStore
|
||||
{
|
||||
private LocalDataStoreElement[] m_DataTable;
|
||||
private LocalDataStoreMgr m_Manager;
|
||||
|
||||
/*=========================================================================
|
||||
** Initialize the data store.
|
||||
=========================================================================*/
|
||||
public LocalDataStore(LocalDataStoreMgr mgr, int InitialCapacity)
|
||||
{
|
||||
// Store the manager of the local data store.
|
||||
m_Manager = mgr;
|
||||
|
||||
// Allocate the array that will contain the data.
|
||||
m_DataTable = new LocalDataStoreElement[InitialCapacity];
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Delete this store from its manager
|
||||
=========================================================================*/
|
||||
internal void Dispose()
|
||||
{
|
||||
m_Manager.DeleteLocalDataStore(this);
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Retrieves the value from the specified slot.
|
||||
=========================================================================*/
|
||||
public Object GetData(LocalDataStoreSlot slot)
|
||||
{
|
||||
// Validate the slot.
|
||||
m_Manager.ValidateSlot(slot);
|
||||
|
||||
// Cache the slot index to avoid synchronization issues.
|
||||
int slotIdx = slot.Slot;
|
||||
|
||||
if (slotIdx >= 0)
|
||||
{
|
||||
// Delay expansion of m_DataTable if we can
|
||||
if (slotIdx >= m_DataTable.Length)
|
||||
return null;
|
||||
|
||||
// Retrieve the data from the given slot.
|
||||
LocalDataStoreElement element = m_DataTable[slotIdx];
|
||||
|
||||
//Initially we prepopulate the elements to be null.
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
// Check that the element is owned by this slot by comparing cookies.
|
||||
// This is necesary to avoid resurection ----s.
|
||||
if (element.Cookie == slot.Cookie)
|
||||
return element.Value;
|
||||
|
||||
// Fall thru and throw exception
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed"));
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Sets the data in the specified slot.
|
||||
=========================================================================*/
|
||||
public void SetData(LocalDataStoreSlot slot, Object data)
|
||||
{
|
||||
// Validate the slot.
|
||||
m_Manager.ValidateSlot(slot);
|
||||
|
||||
// Cache the slot index to avoid synchronization issues.
|
||||
int slotIdx = slot.Slot;
|
||||
|
||||
if (slotIdx >= 0)
|
||||
{
|
||||
LocalDataStoreElement element = (slotIdx < m_DataTable.Length) ? m_DataTable[slotIdx] : null;
|
||||
if (element == null)
|
||||
{
|
||||
element = PopulateElement(slot);
|
||||
}
|
||||
|
||||
// Check that the element is owned by this slot by comparing cookies.
|
||||
// This is necesary to avoid resurection ----s.
|
||||
if (element.Cookie == slot.Cookie)
|
||||
{
|
||||
// Set the data on the given slot.
|
||||
element.Value = data;
|
||||
return;
|
||||
}
|
||||
|
||||
// Fall thru and throw exception
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed"));
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** This method does clears the unused slot.
|
||||
* Assumes lock on m_Manager is taken
|
||||
=========================================================================*/
|
||||
internal void FreeData(int slot, long cookie)
|
||||
{
|
||||
// We try to delay allocate the dataTable (in cases like the manager clearing a
|
||||
// just-freed slot in all stores
|
||||
if (slot >= m_DataTable.Length)
|
||||
return;
|
||||
|
||||
LocalDataStoreElement element = m_DataTable[slot];
|
||||
if (element != null && element.Cookie == cookie)
|
||||
m_DataTable[slot] = null;
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Method used to expand the capacity of the local data store.
|
||||
=========================================================================*/
|
||||
[System.Security.SecuritySafeCritical] // auto-generated
|
||||
private LocalDataStoreElement PopulateElement(LocalDataStoreSlot slot)
|
||||
{
|
||||
bool tookLock = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try {
|
||||
Monitor.Enter(m_Manager, ref tookLock);
|
||||
|
||||
// Make sure that the slot was not freed in the meantime
|
||||
int slotIdx = slot.Slot;
|
||||
if (slotIdx < 0)
|
||||
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed"));
|
||||
|
||||
if (slotIdx >= m_DataTable.Length)
|
||||
{
|
||||
int capacity = m_Manager.GetSlotTableLength();
|
||||
|
||||
// Validate that the specified capacity is larger than the current one.
|
||||
Contract.Assert(capacity >= m_DataTable.Length, "LocalDataStore corrupted: capacity >= m_DataTable.Length");
|
||||
|
||||
// Allocate the new data table.
|
||||
LocalDataStoreElement[] NewDataTable = new LocalDataStoreElement[capacity];
|
||||
|
||||
// Copy all the objects into the new table.
|
||||
Array.Copy(m_DataTable, NewDataTable, m_DataTable.Length);
|
||||
|
||||
// Save the new table.
|
||||
m_DataTable = NewDataTable;
|
||||
}
|
||||
|
||||
// Validate that there is enough space in the local data store now
|
||||
Contract.Assert(slotIdx < m_DataTable.Length, "LocalDataStore corrupted: slotIdx < m_DataTable.Length");
|
||||
|
||||
if (m_DataTable[slotIdx] == null)
|
||||
m_DataTable[slotIdx] = new LocalDataStoreElement(slot.Cookie);
|
||||
|
||||
return m_DataTable[slotIdx];
|
||||
}
|
||||
finally {
|
||||
if (tookLock)
|
||||
Monitor.Exit(m_Manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
341
mcs/class/referencesource/mscorlib/system/_localdatastoremgr.cs
Normal file
341
mcs/class/referencesource/mscorlib/system/_localdatastoremgr.cs
Normal file
@@ -0,0 +1,341 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*=============================================================================
|
||||
**
|
||||
** Class: LocalDataStoreMgr
|
||||
**
|
||||
**
|
||||
** Purpose: Class that manages stores of local data. This class is used in
|
||||
** cooperation with the LocalDataStore class.
|
||||
**
|
||||
**
|
||||
=============================================================================*/
|
||||
namespace System {
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
// This class is an encapsulation of a slot so that it is managed in a secure fashion.
|
||||
// It is constructed by the LocalDataStoreManager, holds the slot and the manager
|
||||
// and cleans up when it is finalized.
|
||||
// This class will not be marked serializable
|
||||
[System.Runtime.InteropServices.ComVisible(true)]
|
||||
public sealed class LocalDataStoreSlot
|
||||
{
|
||||
private LocalDataStoreMgr m_mgr;
|
||||
private int m_slot;
|
||||
private long m_cookie;
|
||||
|
||||
// Construct the object to encapsulate the slot.
|
||||
internal LocalDataStoreSlot(LocalDataStoreMgr mgr, int slot, long cookie)
|
||||
{
|
||||
m_mgr = mgr;
|
||||
m_slot = slot;
|
||||
m_cookie = cookie;
|
||||
}
|
||||
|
||||
// Accessors for the two fields of this class.
|
||||
internal LocalDataStoreMgr Manager
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_mgr;
|
||||
}
|
||||
}
|
||||
internal int Slot
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_slot;
|
||||
}
|
||||
}
|
||||
internal long Cookie
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_cookie;
|
||||
}
|
||||
}
|
||||
|
||||
// Release the slot reserved by this object when this object goes away.
|
||||
~LocalDataStoreSlot()
|
||||
{
|
||||
LocalDataStoreMgr mgr = m_mgr;
|
||||
if (mgr == null)
|
||||
return;
|
||||
|
||||
int slot = m_slot;
|
||||
|
||||
// Mark the slot as free.
|
||||
m_slot = -1;
|
||||
|
||||
mgr.FreeDataSlot(slot, m_cookie);
|
||||
}
|
||||
}
|
||||
|
||||
// This class will not be marked serializable
|
||||
sealed internal class LocalDataStoreMgr
|
||||
{
|
||||
private const int InitialSlotTableSize = 64;
|
||||
private const int SlotTableDoubleThreshold = 512;
|
||||
private const int LargeSlotTableSizeIncrease = 128;
|
||||
|
||||
/*=========================================================================
|
||||
** Create a data store to be managed by this manager and add it to the
|
||||
** list. The initial size of the new store matches the number of slots
|
||||
** allocated in this manager.
|
||||
=========================================================================*/
|
||||
[System.Security.SecuritySafeCritical] // auto-generated
|
||||
public LocalDataStoreHolder CreateLocalDataStore()
|
||||
{
|
||||
// Create a new local data store.
|
||||
LocalDataStore store = new LocalDataStore(this, m_SlotInfoTable.Length);
|
||||
LocalDataStoreHolder holder = new LocalDataStoreHolder(store);
|
||||
|
||||
bool tookLock = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
Monitor.Enter(this, ref tookLock);
|
||||
// Add the store to the array list and return it.
|
||||
m_ManagedLocalDataStores.Add(store);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tookLock)
|
||||
Monitor.Exit(this);
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
* Remove the specified store from the list of managed stores..
|
||||
=========================================================================*/
|
||||
[System.Security.SecuritySafeCritical] // auto-generated
|
||||
public void DeleteLocalDataStore(LocalDataStore store)
|
||||
{
|
||||
bool tookLock = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
Monitor.Enter(this, ref tookLock);
|
||||
// Remove the store to the array list and return it.
|
||||
m_ManagedLocalDataStores.Remove(store);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tookLock)
|
||||
Monitor.Exit(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Allocates a data slot by finding an available index and wrapping it
|
||||
** an object to prevent clients from manipulating it directly, allowing us
|
||||
** to make assumptions its integrity.
|
||||
=========================================================================*/
|
||||
[System.Security.SecuritySafeCritical] // auto-generated
|
||||
public LocalDataStoreSlot AllocateDataSlot()
|
||||
{
|
||||
bool tookLock = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
Monitor.Enter(this, ref tookLock);
|
||||
LocalDataStoreSlot slot;
|
||||
|
||||
int slotTableSize = m_SlotInfoTable.Length;
|
||||
|
||||
// In case FreeDataSlot has moved the pointer back, the next slot may not be available.
|
||||
// Find the first actually available slot.
|
||||
int availableSlot = m_FirstAvailableSlot;
|
||||
while (availableSlot < slotTableSize)
|
||||
{
|
||||
if (!m_SlotInfoTable[availableSlot])
|
||||
break;
|
||||
availableSlot++;
|
||||
}
|
||||
|
||||
// Check if there are any slots left.
|
||||
if (availableSlot >= slotTableSize)
|
||||
{
|
||||
// The table is full so we need to increase its size.
|
||||
int newSlotTableSize;
|
||||
if (slotTableSize < SlotTableDoubleThreshold)
|
||||
{
|
||||
// The table is still relatively small so double it.
|
||||
newSlotTableSize = slotTableSize * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The table is relatively large so simply increase its size by a given amount.
|
||||
newSlotTableSize = slotTableSize + LargeSlotTableSizeIncrease;
|
||||
}
|
||||
|
||||
// Allocate the new slot info table.
|
||||
bool[] newSlotInfoTable = new bool[newSlotTableSize];
|
||||
|
||||
// Copy the old array into the new one.
|
||||
Array.Copy(m_SlotInfoTable, newSlotInfoTable, slotTableSize);
|
||||
m_SlotInfoTable = newSlotInfoTable;
|
||||
}
|
||||
|
||||
// availableSlot is the index of the empty slot.
|
||||
m_SlotInfoTable[availableSlot] = true;
|
||||
|
||||
// We do not need to worry about overflowing m_CookieGenerator. It would take centuries
|
||||
// of intensive slot allocations on current machines to get the 2^64 counter to overflow.
|
||||
// We will perform the increment with overflow check just to play it on the safe side.
|
||||
slot = new LocalDataStoreSlot(this, availableSlot, checked(m_CookieGenerator++));
|
||||
|
||||
// Save the new "first available slot".hint
|
||||
m_FirstAvailableSlot = availableSlot + 1;
|
||||
|
||||
// Return the selected slot
|
||||
return slot;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tookLock)
|
||||
Monitor.Exit(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Allocate a slot and associate a name with it.
|
||||
=========================================================================*/
|
||||
[System.Security.SecuritySafeCritical] // auto-generated
|
||||
public LocalDataStoreSlot AllocateNamedDataSlot(String name)
|
||||
{
|
||||
bool tookLock = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
Monitor.Enter(this, ref tookLock);
|
||||
// Allocate a normal data slot.
|
||||
LocalDataStoreSlot slot = AllocateDataSlot();
|
||||
|
||||
// Insert the association between the name and the data slot number
|
||||
// in the hash table.
|
||||
m_KeyToSlotMap.Add(name, slot);
|
||||
return slot;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tookLock)
|
||||
Monitor.Exit(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Retrieve the slot associated with a name, allocating it if no such
|
||||
** association has been defined.
|
||||
=========================================================================*/
|
||||
[System.Security.SecuritySafeCritical] // auto-generated
|
||||
public LocalDataStoreSlot GetNamedDataSlot(String name)
|
||||
{
|
||||
bool tookLock = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
Monitor.Enter(this, ref tookLock);
|
||||
// Lookup in the hashtable to try find a slot for the name.
|
||||
LocalDataStoreSlot slot = m_KeyToSlotMap.GetValueOrDefault(name);
|
||||
|
||||
// If the name is not yet in the hashtable then add it.
|
||||
if (null == slot)
|
||||
return AllocateNamedDataSlot(name);
|
||||
|
||||
// The name was in the hashtable so return the associated slot.
|
||||
return slot;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tookLock)
|
||||
Monitor.Exit(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Eliminate the association of a name with a slot. The actual slot will
|
||||
** be reclaimed when the finalizer for the slot object runs.
|
||||
=========================================================================*/
|
||||
[System.Security.SecuritySafeCritical] // auto-generated
|
||||
public void FreeNamedDataSlot(String name)
|
||||
{
|
||||
bool tookLock = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
Monitor.Enter(this, ref tookLock);
|
||||
// Remove the name slot association from the hashtable.
|
||||
m_KeyToSlotMap.Remove(name);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tookLock)
|
||||
Monitor.Exit(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Free's a previously allocated data slot on ALL the managed data stores.
|
||||
=========================================================================*/
|
||||
[System.Security.SecuritySafeCritical] // auto-generated
|
||||
internal void FreeDataSlot(int slot, long cookie)
|
||||
{
|
||||
bool tookLock = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
Monitor.Enter(this, ref tookLock);
|
||||
// Go thru all the managed stores and set the data on the specified slot to 0.
|
||||
for (int i = 0; i < m_ManagedLocalDataStores.Count; i++)
|
||||
{
|
||||
((LocalDataStore)m_ManagedLocalDataStores[i]).FreeData(slot, cookie);
|
||||
}
|
||||
|
||||
// Mark the slot as being no longer occupied.
|
||||
m_SlotInfoTable[slot] = false;
|
||||
if (slot < m_FirstAvailableSlot)
|
||||
m_FirstAvailableSlot = slot;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tookLock)
|
||||
Monitor.Exit(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Check that this is a valid slot for this store
|
||||
=========================================================================*/
|
||||
public void ValidateSlot(LocalDataStoreSlot slot)
|
||||
{
|
||||
// Make sure the slot was allocated for this store.
|
||||
if (slot == null || slot.Manager != this)
|
||||
throw new ArgumentException(Environment.GetResourceString("Argument_ALSInvalidSlot"));
|
||||
Contract.EndContractBlock();
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
** Return the number of allocated slots in this manager.
|
||||
=========================================================================*/
|
||||
internal int GetSlotTableLength()
|
||||
{
|
||||
return m_SlotInfoTable.Length;
|
||||
}
|
||||
|
||||
private bool[] m_SlotInfoTable = new bool[InitialSlotTableSize];
|
||||
private int m_FirstAvailableSlot;
|
||||
private List<LocalDataStore> m_ManagedLocalDataStores = new List<LocalDataStore>();
|
||||
private Dictionary<String, LocalDataStoreSlot> m_KeyToSlotMap = new Dictionary<String, LocalDataStoreSlot>();
|
||||
private long m_CookieGenerator;
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*=============================================================================
|
||||
**
|
||||
** Class: AccessViolationException
|
||||
**
|
||||
**
|
||||
** Purpose: Exception class representing an AV that was deemed unsafe and may have corrupted the application.
|
||||
**
|
||||
**
|
||||
=============================================================================*/
|
||||
|
||||
namespace System
|
||||
{
|
||||
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
[System.Runtime.InteropServices.ComVisible(true)]
|
||||
[Serializable]
|
||||
public class AccessViolationException : SystemException
|
||||
{
|
||||
public AccessViolationException()
|
||||
: base(Environment.GetResourceString("Arg_AccessViolationException"))
|
||||
{
|
||||
SetErrorCode(__HResults.E_POINTER);
|
||||
}
|
||||
|
||||
public AccessViolationException(String message)
|
||||
: base(message)
|
||||
{
|
||||
SetErrorCode(__HResults.E_POINTER);
|
||||
}
|
||||
|
||||
public AccessViolationException(String message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
SetErrorCode(__HResults.E_POINTER);
|
||||
}
|
||||
|
||||
protected AccessViolationException(SerializationInfo info, StreamingContext context) : base(info, context) {}
|
||||
|
||||
#pragma warning disable 169 // Field is not used from managed.
|
||||
private IntPtr _ip; // Address of faulting instruction.
|
||||
private IntPtr _target; // Address that could not be accessed.
|
||||
private int _accessType; // 0:read, 1:write
|
||||
#pragma warning restore 169
|
||||
|
||||
}
|
||||
|
||||
}
|
98
mcs/class/referencesource/mscorlib/system/action.cs
Normal file
98
mcs/class/referencesource/mscorlib/system/action.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
// <OWNER>jfree</OWNER>
|
||||
//
|
||||
|
||||
namespace System {
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public delegate void Action<in T>(T obj);
|
||||
|
||||
// Action/Func delegates first shipped with .NET Framework 3.5 in System.Core.dll as part of LINQ
|
||||
// These were type forwarded to mscorlib.dll in .NET Framework 4.0 and in Silverlight 5.0
|
||||
|
||||
#if FEATURE_CORECLR || MOBILE
|
||||
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
|
||||
#else
|
||||
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public delegate void Action();
|
||||
|
||||
#if FEATURE_CORECLR || MOBILE
|
||||
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
|
||||
#else
|
||||
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public delegate void Action<in T1,in T2>(T1 arg1, T2 arg2);
|
||||
|
||||
#if FEATURE_CORECLR || MOBILE
|
||||
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
|
||||
#else
|
||||
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public delegate void Action<in T1,in T2,in T3>(T1 arg1, T2 arg2, T3 arg3);
|
||||
|
||||
#if FEATURE_CORECLR || MOBILE
|
||||
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
|
||||
#else
|
||||
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public delegate void Action<in T1,in T2,in T3,in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
|
||||
#if FEATURE_CORECLR || MOBILE
|
||||
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
|
||||
#else
|
||||
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public delegate TResult Func<out TResult>();
|
||||
|
||||
#if FEATURE_CORECLR || MOBILE
|
||||
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
|
||||
#else
|
||||
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public delegate TResult Func<in T, out TResult>(T arg);
|
||||
|
||||
#if FEATURE_CORECLR || MOBILE
|
||||
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
|
||||
#else
|
||||
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
|
||||
|
||||
#if FEATURE_CORECLR || MOBILE
|
||||
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
|
||||
#else
|
||||
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
|
||||
|
||||
#if FEATURE_CORECLR || MOBILE
|
||||
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
|
||||
#else
|
||||
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
|
||||
|
||||
public delegate void Action<in T1,in T2,in T3,in T4,in T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
|
||||
public delegate int Comparison<in T>(T x, T y);
|
||||
|
||||
public delegate TOutput Converter<in TInput, out TOutput>(TInput input);
|
||||
|
||||
public delegate bool Predicate<in T>(T obj);
|
||||
|
||||
}
|
||||
|
145
mcs/class/referencesource/mscorlib/system/activationarguments.cs
Normal file
145
mcs/class/referencesource/mscorlib/system/activationarguments.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security.Policy;
|
||||
|
||||
namespace System.Runtime.Hosting {
|
||||
[Serializable]
|
||||
[System.Runtime.InteropServices.ComVisible(true)]
|
||||
public sealed class ActivationArguments : EvidenceBase {
|
||||
private ActivationArguments () {}
|
||||
|
||||
// This boolean is used to smuggle the information about whether
|
||||
// AppDomainSetup was constructed from an ActivationContext.
|
||||
private bool m_useFusionActivationContext = false;
|
||||
internal bool UseFusionActivationContext {
|
||||
get {
|
||||
return m_useFusionActivationContext;
|
||||
}
|
||||
}
|
||||
|
||||
// This is used to indicate whether the instance is to be activated
|
||||
// during the new domain's initialization. CreateInstanceHelper sets
|
||||
// this flag to true; CreateDomainHelper never activates the application.
|
||||
private bool m_activateInstance = false;
|
||||
internal bool ActivateInstance {
|
||||
get {
|
||||
return m_activateInstance;
|
||||
}
|
||||
set {
|
||||
m_activateInstance = value;
|
||||
}
|
||||
}
|
||||
|
||||
private string m_appFullName;
|
||||
internal string ApplicationFullName {
|
||||
get {
|
||||
return m_appFullName;
|
||||
}
|
||||
}
|
||||
|
||||
private string[] m_appManifestPaths;
|
||||
internal string[] ApplicationManifestPaths {
|
||||
get {
|
||||
return m_appManifestPaths;
|
||||
}
|
||||
}
|
||||
|
||||
#if !FEATURE_PAL
|
||||
public ActivationArguments (ApplicationIdentity applicationIdentity) : this (applicationIdentity, null) {}
|
||||
public ActivationArguments (ApplicationIdentity applicationIdentity, string[] activationData) {
|
||||
if (applicationIdentity == null)
|
||||
throw new ArgumentNullException("applicationIdentity");
|
||||
Contract.EndContractBlock();
|
||||
|
||||
m_appFullName = applicationIdentity.FullName;
|
||||
m_activationData = activationData;
|
||||
}
|
||||
|
||||
public ActivationArguments (ActivationContext activationData) : this (activationData, null) {}
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
public ActivationArguments (ActivationContext activationContext, string[] activationData) {
|
||||
if (activationContext == null)
|
||||
throw new ArgumentNullException("activationContext");
|
||||
Contract.EndContractBlock();
|
||||
|
||||
m_appFullName = activationContext.Identity.FullName;
|
||||
m_appManifestPaths = activationContext.ManifestPaths;
|
||||
m_activationData = activationData;
|
||||
m_useFusionActivationContext = true;
|
||||
}
|
||||
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
internal ActivationArguments (string appFullName, string[] appManifestPaths, string[] activationData) {
|
||||
if (appFullName == null)
|
||||
throw new ArgumentNullException("appFullName");
|
||||
Contract.EndContractBlock();
|
||||
|
||||
m_appFullName = appFullName;
|
||||
m_appManifestPaths = appManifestPaths;
|
||||
m_activationData = activationData;
|
||||
m_useFusionActivationContext = true;
|
||||
}
|
||||
|
||||
public ApplicationIdentity ApplicationIdentity {
|
||||
get {
|
||||
return new ApplicationIdentity(m_appFullName);
|
||||
}
|
||||
}
|
||||
|
||||
public ActivationContext ActivationContext {
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
get {
|
||||
if (!UseFusionActivationContext)
|
||||
return null;
|
||||
|
||||
if (m_appManifestPaths == null)
|
||||
return new ActivationContext(new ApplicationIdentity(m_appFullName));
|
||||
else
|
||||
return new ActivationContext(new ApplicationIdentity(m_appFullName), m_appManifestPaths);
|
||||
}
|
||||
}
|
||||
#endif // !FEATURE_PAL
|
||||
|
||||
private string[] m_activationData;
|
||||
public string[] ActivationData {
|
||||
get {
|
||||
return m_activationData;
|
||||
}
|
||||
}
|
||||
|
||||
public override EvidenceBase Clone() {
|
||||
ActivationArguments clone = new ActivationArguments();
|
||||
|
||||
clone.m_useFusionActivationContext = m_useFusionActivationContext;
|
||||
clone.m_activateInstance = m_activateInstance;
|
||||
clone.m_appFullName = m_appFullName;
|
||||
|
||||
if (m_appManifestPaths != null) {
|
||||
clone.m_appManifestPaths = new string[m_appManifestPaths.Length];
|
||||
Array.Copy(m_appManifestPaths, clone.m_appManifestPaths, clone.m_appManifestPaths.Length);
|
||||
}
|
||||
|
||||
if (m_activationData != null) {
|
||||
clone.m_activationData = new string[m_activationData.Length];
|
||||
Array.Copy(m_activationData, clone.m_activationData, clone.m_activationData.Length);
|
||||
}
|
||||
|
||||
#if !FEATURE_PAL
|
||||
clone.m_activateInstance = m_activateInstance;
|
||||
clone.m_appFullName = m_appFullName;
|
||||
clone.m_useFusionActivationContext = m_useFusionActivationContext;
|
||||
#endif // !FEATURE_PAL
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
615
mcs/class/referencesource/mscorlib/system/activationcontext.cs
Normal file
615
mcs/class/referencesource/mscorlib/system/activationcontext.cs
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user