diff options
Diffstat (limited to 'src/mscorlib/src/System/Threading')
50 files changed, 1226 insertions, 3277 deletions
diff --git a/src/mscorlib/src/System/Threading/AsyncLocal.cs b/src/mscorlib/src/System/Threading/AsyncLocal.cs index 264f2a6ff7..6ed1545ac7 100644 --- a/src/mscorlib/src/System/Threading/AsyncLocal.cs +++ b/src/mscorlib/src/System/Threading/AsyncLocal.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Security; @@ -40,7 +41,6 @@ namespace System.Threading // public sealed class AsyncLocal<T> : IAsyncLocal { - [SecurityCritical] // critical because this action will terminate the process if it throws. private readonly Action<AsyncLocalValueChangedArgs<T>> m_valueChangedHandler; // @@ -54,7 +54,6 @@ namespace System.Threading // Constructs an AsyncLocal<T> with a delegate that is called whenever the current value changes // on any thread. // - [SecurityCritical] public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler) { m_valueChangedHandler = valueChangedHandler; @@ -62,23 +61,20 @@ namespace System.Threading public T Value { - [SecuritySafeCritical] get { object obj = ExecutionContext.GetLocalValue(this); return (obj == null) ? default(T) : (T)obj; } - [SecuritySafeCritical] set { ExecutionContext.SetLocalValue(this, value, m_valueChangedHandler != null); } } - [SecurityCritical] void IAsyncLocal.OnValueChanged(object previousValueObj, object currentValueObj, bool contextChanged) { - Contract.Assert(m_valueChangedHandler != null); + Debug.Assert(m_valueChangedHandler != null); T previousValue = previousValueObj == null ? default(T) : (T)previousValueObj; T currentValue = currentValueObj == null ? default(T) : (T)currentValueObj; m_valueChangedHandler(new AsyncLocalValueChangedArgs<T>(previousValue, currentValue, contextChanged)); @@ -90,7 +86,6 @@ namespace System.Threading // internal interface IAsyncLocal { - [SecurityCritical] void OnValueChanged(object previousValue, object currentValue, bool contextChanged); } @@ -113,4 +108,382 @@ namespace System.Threading ThreadContextChanged = contextChanged; } } + + // + // Interface used to store an IAsyncLocal => object mapping in ExecutionContext. + // Implementations are specialized based on the number of elements in the immutable + // map in order to minimize memory consumption and look-up times. + // + interface IAsyncLocalValueMap + { + bool TryGetValue(IAsyncLocal key, out object value); + IAsyncLocalValueMap Set(IAsyncLocal key, object value); + } + + // + // Utility functions for getting/creating instances of IAsyncLocalValueMap + // + internal static class AsyncLocalValueMap + { + public static IAsyncLocalValueMap Empty { get; } = new EmptyAsyncLocalValueMap(); + + public static IAsyncLocalValueMap Create(IAsyncLocal key, object value) => new OneElementAsyncLocalValueMap(key, value); + + // Instance without any key/value pairs. Used as a singleton/ + private sealed class EmptyAsyncLocalValueMap : IAsyncLocalValueMap + { + public IAsyncLocalValueMap Set(IAsyncLocal key, object value) + { + // If the value isn't null, then create a new one-element map to store + // the key/value pair. If it is null, then we're still empty. + return value != null ? + new OneElementAsyncLocalValueMap(key, value) : + (IAsyncLocalValueMap)this; + } + + public bool TryGetValue(IAsyncLocal key, out object value) + { + value = null; + return false; + } + } + + // Instance with one key/value pair. + private sealed class OneElementAsyncLocalValueMap : IAsyncLocalValueMap + { + private readonly IAsyncLocal _key1; + private readonly object _value1; + + public OneElementAsyncLocalValueMap(IAsyncLocal key, object value) + { + _key1 = key; _value1 = value; + } + + public IAsyncLocalValueMap Set(IAsyncLocal key, object value) + { + if (value != null) + { + // The value is non-null. If the key matches one already contained in this map, + // then create a new one-element map with the updated value, otherwise create + // a two-element map with the additional key/value. + return ReferenceEquals(key, _key1) ? + new OneElementAsyncLocalValueMap(key, value) : + (IAsyncLocalValueMap)new TwoElementAsyncLocalValueMap(_key1, _value1, key, value); + } + else + { + // The value is null. If the key exists in this map, remove it by downgrading to an empty map. + // Otherwise, there's nothing to add or remove, so just return this map. + return ReferenceEquals(key, _key1) ? + Empty : + (IAsyncLocalValueMap)this; + } + } + + public bool TryGetValue(IAsyncLocal key, out object value) + { + if (ReferenceEquals(key, _key1)) + { + value = _value1; + return true; + } + else + { + value = null; + return false; + } + } + } + + // Instance with two key/value pairs. + private sealed class TwoElementAsyncLocalValueMap : IAsyncLocalValueMap + { + private readonly IAsyncLocal _key1, _key2; + private readonly object _value1, _value2; + + public TwoElementAsyncLocalValueMap(IAsyncLocal key1, object value1, IAsyncLocal key2, object value2) + { + _key1 = key1; _value1 = value1; + _key2 = key2; _value2 = value2; + } + + public IAsyncLocalValueMap Set(IAsyncLocal key, object value) + { + if (value != null) + { + // The value is non-null. If the key matches one already contained in this map, + // then create a new two-element map with the updated value, otherwise create + // a three-element map with the additional key/value. + return + ReferenceEquals(key, _key1) ? new TwoElementAsyncLocalValueMap(key, value, _key2, _value2) : + ReferenceEquals(key, _key2) ? new TwoElementAsyncLocalValueMap(_key1, _value1, key, value) : + (IAsyncLocalValueMap)new ThreeElementAsyncLocalValueMap(_key1, _value1, _key2, _value2, key, value); + } + else + { + // The value is null. If the key exists in this map, remove it by downgrading to a one-element map + // without the key. Otherwise, there's nothing to add or remove, so just return this map. + return + ReferenceEquals(key, _key1) ? new OneElementAsyncLocalValueMap(_key2, _value2) : + ReferenceEquals(key, _key2) ? new OneElementAsyncLocalValueMap(_key1, _value1) : + (IAsyncLocalValueMap)this; + } + } + + public bool TryGetValue(IAsyncLocal key, out object value) + { + if (ReferenceEquals(key, _key1)) + { + value = _value1; + return true; + } + else if (ReferenceEquals(key, _key2)) + { + value = _value2; + return true; + } + else + { + value = null; + return false; + } + } + } + + // Instance with three key/value pairs. + private sealed class ThreeElementAsyncLocalValueMap : IAsyncLocalValueMap + { + private readonly IAsyncLocal _key1, _key2, _key3; + private readonly object _value1, _value2, _value3; + + public ThreeElementAsyncLocalValueMap(IAsyncLocal key1, object value1, IAsyncLocal key2, object value2, IAsyncLocal key3, object value3) + { + _key1 = key1; _value1 = value1; + _key2 = key2; _value2 = value2; + _key3 = key3; _value3 = value3; + } + + public IAsyncLocalValueMap Set(IAsyncLocal key, object value) + { + if (value != null) + { + // The value is non-null. If the key matches one already contained in this map, + // then create a new three-element map with the updated value. + if (ReferenceEquals(key, _key1)) return new ThreeElementAsyncLocalValueMap(key, value, _key2, _value2, _key3, _value3); + if (ReferenceEquals(key, _key2)) return new ThreeElementAsyncLocalValueMap(_key1, _value1, key, value, _key3, _value3); + if (ReferenceEquals(key, _key3)) return new ThreeElementAsyncLocalValueMap(_key1, _value1, _key2, _value2, key, value); + + // The key doesn't exist in this map, so upgrade to a multi map that contains + // the additional key/value pair. + var multi = new MultiElementAsyncLocalValueMap(4); + multi.UnsafeStore(0, _key1, _value1); + multi.UnsafeStore(1, _key2, _value2); + multi.UnsafeStore(2, _key3, _value3); + multi.UnsafeStore(3, key, value); + return multi; + } + else + { + // The value is null. If the key exists in this map, remove it by downgrading to a two-element map + // without the key. Otherwise, there's nothing to add or remove, so just return this map. + return + ReferenceEquals(key, _key1) ? new TwoElementAsyncLocalValueMap(_key2, _value2, _key3, _value3) : + ReferenceEquals(key, _key2) ? new TwoElementAsyncLocalValueMap(_key1, _value1, _key3, _value3) : + ReferenceEquals(key, _key3) ? new TwoElementAsyncLocalValueMap(_key1, _value1, _key2, _value2) : + (IAsyncLocalValueMap)this; + } + } + + public bool TryGetValue(IAsyncLocal key, out object value) + { + if (ReferenceEquals(key, _key1)) + { + value = _value1; + return true; + } + else if (ReferenceEquals(key, _key2)) + { + value = _value2; + return true; + } + else if (ReferenceEquals(key, _key3)) + { + value = _value3; + return true; + } + else + { + value = null; + return false; + } + } + } + + // Instance with up to 16 key/value pairs. + private sealed class MultiElementAsyncLocalValueMap : IAsyncLocalValueMap + { + internal const int MaxMultiElements = 16; + private readonly KeyValuePair<IAsyncLocal, object>[] _keyValues; + + internal MultiElementAsyncLocalValueMap(int count) + { + Debug.Assert(count <= MaxMultiElements); + _keyValues = new KeyValuePair<IAsyncLocal, object>[count]; + } + + internal void UnsafeStore(int index, IAsyncLocal key, object value) + { + Debug.Assert(index < _keyValues.Length); + _keyValues[index] = new KeyValuePair<IAsyncLocal, object>(key, value); + } + + public IAsyncLocalValueMap Set(IAsyncLocal key, object value) + { + // Find the key in this map. + for (int i = 0; i < _keyValues.Length; i++) + { + if (ReferenceEquals(key, _keyValues[i].Key)) + { + // The key is in the map. If the value isn't null, then create a new map of the same + // size that has all of the same pairs, with this new key/value pair overwriting the old. + if (value != null) + { + var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length); + Array.Copy(_keyValues, 0, multi._keyValues, 0, _keyValues.Length); + multi._keyValues[i] = new KeyValuePair<IAsyncLocal, object>(key, value); + return multi; + } + else if (_keyValues.Length == 4) + { + // The value is null, and we only have four elements, one of which we're removing, + // so downgrade to a three-element map, without the matching element. + return + i == 0 ? new ThreeElementAsyncLocalValueMap(_keyValues[1].Key, _keyValues[1].Value, _keyValues[2].Key, _keyValues[2].Value, _keyValues[3].Key, _keyValues[3].Value) : + i == 1 ? new ThreeElementAsyncLocalValueMap(_keyValues[0].Key, _keyValues[0].Value, _keyValues[2].Key, _keyValues[2].Value, _keyValues[3].Key, _keyValues[3].Value) : + i == 2 ? new ThreeElementAsyncLocalValueMap(_keyValues[0].Key, _keyValues[0].Value, _keyValues[1].Key, _keyValues[1].Value, _keyValues[3].Key, _keyValues[3].Value) : + (IAsyncLocalValueMap)new ThreeElementAsyncLocalValueMap(_keyValues[0].Key, _keyValues[0].Value, _keyValues[1].Key, _keyValues[1].Value, _keyValues[2].Key, _keyValues[2].Value); + } + else + { + // The value is null, and we have enough elements remaining to warrant a multi map. + // Create a new one and copy all of the elements from this one, except the one to be removed. + var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length - 1); + if (i != 0) Array.Copy(_keyValues, 0, multi._keyValues, 0, i); + if (i != _keyValues.Length - 1) Array.Copy(_keyValues, i + 1, multi._keyValues, i, _keyValues.Length - i - 1); + return multi; + } + } + } + + // The key does not already exist in this map. + + // If the value is null, then we can simply return this same map, as there's nothing to add or remove. + if (value == null) + { + return this; + } + + // We need to create a new map that has the additional key/value pair. + // If with the addition we can still fit in a multi map, create one. + if (_keyValues.Length < MaxMultiElements) + { + var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length + 1); + Array.Copy(_keyValues, 0, multi._keyValues, 0, _keyValues.Length); + multi._keyValues[_keyValues.Length] = new KeyValuePair<IAsyncLocal, object>(key, value); + return multi; + } + + // Otherwise, upgrade to a many map. + var many = new ManyElementAsyncLocalValueMap(MaxMultiElements + 1); + foreach (KeyValuePair<IAsyncLocal, object> pair in _keyValues) + { + many[pair.Key] = pair.Value; + } + many[key] = value; + return many; + } + + public bool TryGetValue(IAsyncLocal key, out object value) + { + foreach (KeyValuePair<IAsyncLocal, object> pair in _keyValues) + { + if (ReferenceEquals(key, pair.Key)) + { + value = pair.Value; + return true; + } + } + value = null; + return false; + } + } + + // Instance with any number of key/value pairs. + private sealed class ManyElementAsyncLocalValueMap : Dictionary<IAsyncLocal, object>, IAsyncLocalValueMap + { + public ManyElementAsyncLocalValueMap(int capacity) : base(capacity) { } + + public IAsyncLocalValueMap Set(IAsyncLocal key, object value) + { + int count = Count; + bool containsKey = ContainsKey(key); + + // If the value being set exists, create a new many map, copy all of the elements from this one, + // and then store the new key/value pair into it. This is the most common case. + if (value != null) + { + var map = new ManyElementAsyncLocalValueMap(count + (containsKey ? 0 : 1)); + foreach (KeyValuePair<IAsyncLocal, object> pair in this) + { + map[pair.Key] = pair.Value; + } + map[key] = value; + return map; + } + + // Otherwise, the value is null, which means null is being stored into an AsyncLocal.Value. + // Since there's no observable difference at the API level between storing null and the key + // not existing at all, we can downgrade to a smaller map rather than storing null. + + // If the key is contained in this map, we're going to create a new map that's one pair smaller. + if (containsKey) + { + // If the new count would be within range of a multi map instead of a many map, + // downgrade to the many map, which uses less memory and is faster to access. + // Otherwise, just create a new many map that's missing this key. + if (count == MultiElementAsyncLocalValueMap.MaxMultiElements + 1) + { + var multi = new MultiElementAsyncLocalValueMap(MultiElementAsyncLocalValueMap.MaxMultiElements); + int index = 0; + foreach (KeyValuePair<IAsyncLocal, object> pair in this) + { + if (!ReferenceEquals(key, pair.Key)) + { + multi.UnsafeStore(index++, pair.Key, pair.Value); + } + } + Debug.Assert(index == MultiElementAsyncLocalValueMap.MaxMultiElements); + return multi; + } + else + { + var map = new ManyElementAsyncLocalValueMap(count - 1); + foreach (KeyValuePair<IAsyncLocal, object> pair in this) + { + if (!ReferenceEquals(key, pair.Key)) + { + map[pair.Key] = pair.Value; + } + } + Debug.Assert(map.Count == count - 1); + return map; + } + } + + // We were storing null, but the key wasn't in the map, so there's nothing to change. + // Just return this instance. + return this; + } + } + } } diff --git a/src/mscorlib/src/System/Threading/AutoResetEvent.cs b/src/mscorlib/src/System/Threading/AutoResetEvent.cs index 6fe6c06232..78a6fa1234 100644 --- a/src/mscorlib/src/System/Threading/AutoResetEvent.cs +++ b/src/mscorlib/src/System/Threading/AutoResetEvent.cs @@ -17,7 +17,6 @@ namespace System.Threading { using System.Security.Permissions; using System.Runtime.InteropServices; - [HostProtection(Synchronization=true, ExternalThreading=true)] [System.Runtime.InteropServices.ComVisible(true)] public sealed class AutoResetEvent : EventWaitHandle { diff --git a/src/mscorlib/src/System/Threading/CancellationToken.cs b/src/mscorlib/src/System/Threading/CancellationToken.cs index 48a2344c31..5b78f20900 100644 --- a/src/mscorlib/src/System/Threading/CancellationToken.cs +++ b/src/mscorlib/src/System/Threading/CancellationToken.cs @@ -8,9 +8,9 @@ #pragma warning disable 0420 // turn off 'a reference to a volatile field will not be treated as volatile' during CAS. using System; -using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Permissions; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime; using System.Runtime.CompilerServices; @@ -39,7 +39,6 @@ namespace System.Threading /// </para> /// </remarks> [ComVisible(false)] - [HostProtection(Synchronization = true, ExternalThreading = true)] [DebuggerDisplay("IsCancellationRequested = {IsCancellationRequested}")] public struct CancellationToken { @@ -167,7 +166,7 @@ namespace System.Threading private static void ActionToActionObjShunt(object obj) { Action action = obj as Action; - Contract.Assert(action != null, "Expected an Action here"); + Debug.Assert(action != null, "Expected an Action here"); action(); } @@ -192,7 +191,7 @@ namespace System.Threading public CancellationTokenRegistration Register(Action callback) { if (callback == null) - throw new ArgumentNullException("callback"); + throw new ArgumentNullException(nameof(callback)); return Register( s_ActionToActionObjShunt, @@ -227,7 +226,7 @@ namespace System.Threading public CancellationTokenRegistration Register(Action callback, bool useSynchronizationContext) { if (callback == null) - throw new ArgumentNullException("callback"); + throw new ArgumentNullException(nameof(callback)); return Register( s_ActionToActionObjShunt, @@ -260,7 +259,7 @@ namespace System.Threading public CancellationTokenRegistration Register(Action<Object> callback, Object state) { if (callback == null) - throw new ArgumentNullException("callback"); + throw new ArgumentNullException(nameof(callback)); return Register( callback, @@ -318,14 +317,13 @@ namespace System.Threading } // the real work.. - [SecuritySafeCritical] [MethodImpl(MethodImplOptions.NoInlining)] private CancellationTokenRegistration Register(Action<Object> callback, Object state, bool useSynchronizationContext, bool useExecutionContext) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; if (callback == null) - throw new ArgumentNullException("callback"); + throw new ArgumentNullException(nameof(callback)); if (CanBeCanceled == false) { diff --git a/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs b/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs index 34e0bb0aba..ac27fe30e6 100644 --- a/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs +++ b/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs @@ -17,7 +17,6 @@ namespace System.Threading /// <remarks> /// To unregister a callback, dispose the corresponding Registration instance. /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public struct CancellationTokenRegistration : IEquatable<CancellationTokenRegistration>, IDisposable { private readonly CancellationCallbackInfo m_callbackInfo; diff --git a/src/mscorlib/src/System/Threading/CancellationTokenSource.cs b/src/mscorlib/src/System/Threading/CancellationTokenSource.cs index 954cd38344..fe9e0dec76 100644 --- a/src/mscorlib/src/System/Threading/CancellationTokenSource.cs +++ b/src/mscorlib/src/System/Threading/CancellationTokenSource.cs @@ -11,6 +11,7 @@ using System.Security; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Security.Permissions; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime; @@ -35,7 +36,6 @@ namespace System.Threading /// </para> /// </remarks> [ComVisible(false)] - [HostProtection(Synchronization = true, ExternalThreading = true)] public class CancellationTokenSource : IDisposable { @@ -275,7 +275,7 @@ namespace System.Threading long totalMilliseconds = (long)delay.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue) { - throw new ArgumentOutOfRangeException("delay"); + throw new ArgumentOutOfRangeException(nameof(delay)); } InitializeWithTimer((int)totalMilliseconds); @@ -304,7 +304,7 @@ namespace System.Threading { if (millisecondsDelay < -1) { - throw new ArgumentOutOfRangeException("millisecondsDelay"); + throw new ArgumentOutOfRangeException(nameof(millisecondsDelay)); } InitializeWithTimer(millisecondsDelay); @@ -414,7 +414,7 @@ namespace System.Threading long totalMilliseconds = (long)delay.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue) { - throw new ArgumentOutOfRangeException("delay"); + throw new ArgumentOutOfRangeException(nameof(delay)); } CancelAfter((int)totalMilliseconds); @@ -450,7 +450,7 @@ namespace System.Threading if (millisecondsDelay < -1) { - throw new ArgumentOutOfRangeException("millisecondsDelay"); + throw new ArgumentOutOfRangeException(nameof(millisecondsDelay)); } if (IsCancellationRequested) return; @@ -629,7 +629,7 @@ namespace System.Threading } // the CancellationToken has already checked that the token is cancelable before calling this method. - Contract.Assert(CanBeCanceled, "Cannot register for uncancelable token src"); + Debug.Assert(CanBeCanceled, "Cannot register for uncancelable token src"); // if not canceled, register the event handlers // if canceled already, run the callback synchronously @@ -730,7 +730,7 @@ namespace System.Threading // - After transition, no more delegates will be added to the // - list of handlers, and hence it can be consumed and cleared at leisure by ExecuteCallbackHandlers. ExecuteCallbackHandlers(throwOnFirstException); - Contract.Assert(IsCancellationCompleted, "Expected cancellation to have finished"); + Debug.Assert(IsCancellationCompleted, "Expected cancellation to have finished"); } } @@ -742,8 +742,8 @@ namespace System.Threading /// </remarks> private void ExecuteCallbackHandlers(bool throwOnFirstException) { - Contract.Assert(IsCancellationRequested, "ExecuteCallbackHandlers should only be called after setting IsCancellationRequested->true"); - Contract.Assert(ThreadIDExecutingCallbacks != -1, "ThreadIDExecutingCallbacks should have been set."); + Debug.Assert(IsCancellationRequested, "ExecuteCallbackHandlers should only be called after setting IsCancellationRequested->true"); + Debug.Assert(ThreadIDExecutingCallbacks != -1, "ThreadIDExecutingCallbacks should have been set."); // Design decision: call the delegates in LIFO order so that callbacks fire 'deepest first'. // This is intended to help with nesting scenarios so that child enlisters cancel before their parents. @@ -791,7 +791,7 @@ namespace System.Threading var wsc = m_executingCallback as CancellationCallbackInfo.WithSyncContext; if (wsc != null) { - Contract.Assert(wsc.TargetSyncContext != null, "Should only have derived CCI if non-null SyncCtx"); + Debug.Assert(wsc.TargetSyncContext != null, "Should only have derived CCI if non-null SyncCtx"); wsc.TargetSyncContext.Send(CancellationCallbackCoreWork_OnSyncContext, args); // CancellationCallbackCoreWork_OnSyncContext may have altered ThreadIDExecutingCallbacks, so reset it. ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId; @@ -828,7 +828,7 @@ namespace System.Threading if (exceptionList != null) { - Contract.Assert(exceptionList.Count > 0, "Expected exception count > 0"); + Debug.Assert(exceptionList.Count > 0, "Expected exception count > 0"); throw new AggregateException(exceptionList); } } @@ -882,7 +882,7 @@ namespace System.Threading public static CancellationTokenSource CreateLinkedTokenSource(params CancellationToken[] tokens) { if (tokens == null) - throw new ArgumentNullException("tokens"); + throw new ArgumentNullException(nameof(tokens)); if (tokens.Length == 0) throw new ArgumentException(Environment.GetResourceString("CancellationToken_CreateLinkedToken_TokensIsEmpty")); @@ -1029,14 +1029,12 @@ namespace System.Threading } // Cached callback delegate that's lazily initialized due to ContextCallback being SecurityCritical - [SecurityCritical] private static ContextCallback s_executionContextCallback; /// <summary> /// InternalExecuteCallbackSynchronously_GeneralPath /// This will be called on the target synchronization context, however, we still need to restore the required execution context /// </summary> - [SecuritySafeCritical] internal void ExecuteCallback() { if (TargetExecutionContext != null) @@ -1059,11 +1057,10 @@ namespace System.Threading // the worker method to actually run the callback // The signature is such that it can be used as a 'ContextCallback' - [SecurityCritical] private static void ExecutionContextCallback(object obj) { CancellationCallbackInfo callbackInfo = obj as CancellationCallbackInfo; - Contract.Assert(callbackInfo != null); + Debug.Assert(callbackInfo != null); callbackInfo.Callback(callbackInfo.StateForCallback); } } @@ -1147,14 +1144,14 @@ namespace System.Threading start = 0; curr.m_freeCount--; // Too many free elements; fix up. } - Contract.Assert(start >= 0 && start < c, "start is outside of bounds"); + Debug.Assert(start >= 0 && start < c, "start is outside of bounds"); // Now walk the array until we find a free slot (or reach the end). for (int i = 0; i < c; i++) { // If the slot is null, try to CAS our element into it. int tryIndex = (start + i) % c; - Contract.Assert(tryIndex >= 0 && tryIndex < curr.m_elements.Length, "tryIndex is outside of bounds"); + Debug.Assert(tryIndex >= 0 && tryIndex < curr.m_elements.Length, "tryIndex is outside of bounds"); if (curr.m_elements[tryIndex] == null && Interlocked.CompareExchange(ref curr.m_elements[tryIndex], element, null) == null) { @@ -1193,8 +1190,8 @@ namespace System.Threading internal SparselyPopulatedArrayAddInfo(SparselyPopulatedArrayFragment<T> source, int index) { - Contract.Assert(source != null); - Contract.Assert(index >= 0 && index < source.Length); + Debug.Assert(source != null); + Debug.Assert(index >= 0 && index < source.Length); m_source = source; m_index = index; } diff --git a/src/mscorlib/src/System/Threading/CountdownEvent.cs b/src/mscorlib/src/System/Threading/CountdownEvent.cs index 1374766863..d86a2ccfb8 100644 --- a/src/mscorlib/src/System/Threading/CountdownEvent.cs +++ b/src/mscorlib/src/System/Threading/CountdownEvent.cs @@ -11,10 +11,10 @@ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; -using System.Diagnostics; using System.Security.Permissions; using System.Runtime.InteropServices; using System.Threading; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace System.Threading @@ -32,7 +32,6 @@ namespace System.Threading /// </remarks> [ComVisible(false)] [DebuggerDisplay("Initial Count={InitialCount}, Current Count={CurrentCount}")] - [HostProtection(Synchronization = true, ExternalThreading = true)] public class CountdownEvent : IDisposable { // CountdownEvent is a simple synchronization primitive used for fork/join parallelism. We create a @@ -59,7 +58,7 @@ namespace System.Threading { if (initialCount < 0) { - throw new ArgumentOutOfRangeException("initialCount"); + throw new ArgumentOutOfRangeException(nameof(initialCount)); } m_initialCount = initialCount; @@ -186,7 +185,7 @@ namespace System.Threading public bool Signal() { ThrowIfDisposed(); - Contract.Assert(m_event != null); + Debug.Assert(m_event != null); if (m_currentCount <= 0) { @@ -229,11 +228,11 @@ namespace System.Threading { if (signalCount <= 0) { - throw new ArgumentOutOfRangeException("signalCount"); + throw new ArgumentOutOfRangeException(nameof(signalCount)); } ThrowIfDisposed(); - Contract.Assert(m_event != null); + Debug.Assert(m_event != null); int observedCount; SpinWait spin = new SpinWait(); @@ -267,7 +266,7 @@ namespace System.Threading return true; } - Contract.Assert(m_currentCount >= 0, "latch was decremented below zero"); + Debug.Assert(m_currentCount >= 0, "latch was decremented below zero"); return false; } @@ -340,7 +339,7 @@ namespace System.Threading { if (signalCount <= 0) { - throw new ArgumentOutOfRangeException("signalCount"); + throw new ArgumentOutOfRangeException(nameof(signalCount)); } ThrowIfDisposed(); @@ -409,7 +408,7 @@ namespace System.Threading if (count < 0) { - throw new ArgumentOutOfRangeException("count"); + throw new ArgumentOutOfRangeException(nameof(count)); } m_currentCount = count; @@ -481,7 +480,7 @@ namespace System.Threading long totalMilliseconds = (long)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException("timeout"); + throw new ArgumentOutOfRangeException(nameof(timeout)); } return Wait((int)totalMilliseconds, new CancellationToken()); @@ -511,7 +510,7 @@ namespace System.Threading long totalMilliseconds = (long)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException("timeout"); + throw new ArgumentOutOfRangeException(nameof(timeout)); } return Wait((int)totalMilliseconds, cancellationToken); @@ -555,7 +554,7 @@ namespace System.Threading { if (millisecondsTimeout < -1) { - throw new ArgumentOutOfRangeException("millisecondsTimeout"); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); } ThrowIfDisposed(); diff --git a/src/mscorlib/src/System/Threading/EventWaitHandle.cs b/src/mscorlib/src/System/Threading/EventWaitHandle.cs index f56da1fa26..4b1611c6aa 100644 --- a/src/mscorlib/src/System/Threading/EventWaitHandle.cs +++ b/src/mscorlib/src/System/Threading/EventWaitHandle.cs @@ -13,7 +13,6 @@ =============================================================================*/ -#if !FEATURE_MACL namespace System.Security.AccessControl { public class EventWaitHandleSecurity @@ -23,7 +22,6 @@ namespace System.Security.AccessControl { } } -#endif namespace System.Threading { @@ -39,14 +37,11 @@ namespace System.Threading using System.Security.AccessControl; using System.Diagnostics.Contracts; - [HostProtection(Synchronization=true, ExternalThreading=true)] [ComVisibleAttribute(true)] public class EventWaitHandle : WaitHandle { - [System.Security.SecuritySafeCritical] // auto-generated public EventWaitHandle(bool initialState, EventResetMode mode) : this(initialState,mode,null) { } - [System.Security.SecurityCritical] // auto-generated_required public EventWaitHandle(bool initialState, EventResetMode mode, string name) { if(name != null) @@ -56,7 +51,7 @@ namespace System.Threading #else if (System.IO.Path.MaxPath < name.Length) { - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name)); } #endif } @@ -89,13 +84,11 @@ namespace System.Threading SetHandleInternal(_handle); } - [System.Security.SecurityCritical] // auto-generated_required public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew) : this(initialState, mode, name, out createdNew, null) { } - [System.Security.SecurityCritical] // auto-generated_required public unsafe EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity) { if(name != null) @@ -105,24 +98,12 @@ namespace System.Threading #else if (System.IO.Path.MaxPath < name.Length) { - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name)); } #endif } Contract.EndContractBlock(); Win32Native.SECURITY_ATTRIBUTES secAttrs = null; -#if FEATURE_MACL - // For ACL's, get the security descriptor from the EventWaitHandleSecurity. - if (eventSecurity != null) { - secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); - secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); - - byte[] sd = eventSecurity.GetSecurityDescriptorBinaryForm(); - byte* pSecDescriptor = stackalloc byte[sd.Length]; - Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length); - secAttrs.pSecurityDescriptor = pSecDescriptor; - } -#endif SafeWaitHandle _handle = null; Boolean isManualReset; @@ -155,23 +136,16 @@ namespace System.Threading SetHandleInternal(_handle); } - [System.Security.SecurityCritical] // auto-generated private EventWaitHandle(SafeWaitHandle handle) { SetHandleInternal(handle); } - [System.Security.SecurityCritical] // auto-generated_required public static EventWaitHandle OpenExisting(string name) { -#if !FEATURE_MACL return OpenExisting(name, (EventWaitHandleRights)0); -#else - return OpenExisting(name, EventWaitHandleRights.Modify | EventWaitHandleRights.Synchronize); -#endif } - [System.Security.SecurityCritical] // auto-generated_required public static EventWaitHandle OpenExisting(string name, EventWaitHandleRights rights) { EventWaitHandle result; @@ -192,23 +166,16 @@ namespace System.Threading } } - [System.Security.SecurityCritical] // auto-generated_required public static bool TryOpenExisting(string name, out EventWaitHandle result) { -#if !FEATURE_MACL return OpenExistingWorker(name, (EventWaitHandleRights)0, out result) == OpenExistingResult.Success; -#else - return OpenExistingWorker(name, EventWaitHandleRights.Modify | EventWaitHandleRights.Synchronize, out result) == OpenExistingResult.Success; -#endif } - [System.Security.SecurityCritical] // auto-generated_required public static bool TryOpenExisting(string name, EventWaitHandleRights rights, out EventWaitHandle result) { return OpenExistingWorker(name, rights, out result) == OpenExistingResult.Success; } - [System.Security.SecurityCritical] // auto-generated_required private static OpenExistingResult OpenExistingWorker(string name, EventWaitHandleRights rights, out EventWaitHandle result) { #if PLATFORM_UNIX @@ -216,29 +183,25 @@ namespace System.Threading #else if (name == null) { - throw new ArgumentNullException("name", Environment.GetResourceString("ArgumentNull_WithParamName")); + throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_WithParamName")); } if(name.Length == 0) { - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name)); } if(null != name && System.IO.Path.MaxPath < name.Length) { - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name)); } Contract.EndContractBlock(); result = null; -#if FEATURE_MACL - SafeWaitHandle myHandle = Win32Native.OpenEvent((int) rights, false, name); -#else SafeWaitHandle myHandle = Win32Native.OpenEvent(Win32Native.EVENT_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name); -#endif - + if (myHandle.IsInvalid) { int errorCode = Marshal.GetLastWin32Error(); @@ -256,7 +219,6 @@ namespace System.Threading return OpenExistingResult.Success; #endif } - [System.Security.SecuritySafeCritical] // auto-generated public bool Reset() { bool res = Win32Native.ResetEvent(safeWaitHandle); @@ -264,7 +226,6 @@ namespace System.Threading __Error.WinIOError(); return res; } - [System.Security.SecuritySafeCritical] // auto-generated public bool Set() { bool res = Win32Native.SetEvent(safeWaitHandle); @@ -274,24 +235,6 @@ namespace System.Threading return res; } - -#if FEATURE_MACL - [System.Security.SecuritySafeCritical] // auto-generated - public EventWaitHandleSecurity GetAccessControl() - { - return new EventWaitHandleSecurity(safeWaitHandle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group); - } - - [System.Security.SecuritySafeCritical] // auto-generated - public void SetAccessControl(EventWaitHandleSecurity eventSecurity) - { - if (eventSecurity == null) - throw new ArgumentNullException("eventSecurity"); - Contract.EndContractBlock(); - - eventSecurity.Persist(safeWaitHandle); - } -#endif } } diff --git a/src/mscorlib/src/System/Threading/ExecutionContext.cs b/src/mscorlib/src/System/Threading/ExecutionContext.cs index 0440368608..5ea9942f65 100644 --- a/src/mscorlib/src/System/Threading/ExecutionContext.cs +++ b/src/mscorlib/src/System/Threading/ExecutionContext.cs @@ -14,33 +14,22 @@ namespace System.Threading using System; using System.Security; using System.Runtime.Remoting; -#if FEATURE_IMPERSONATION - using System.Security.Principal; -#endif using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Runtime.ExceptionServices; using System.Runtime.Serialization; using System.Security.Permissions; -#if FEATURE_REMOTING - using System.Runtime.Remoting.Messaging; -#endif // FEATURE_REMOTING using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; + using System.Diagnostics; using System.Diagnostics.Contracts; using System.Diagnostics.CodeAnalysis; -#if FEATURE_CORECLR - [System.Security.SecurityCritical] // auto-generated -#endif [System.Runtime.InteropServices.ComVisible(true)] public delegate void ContextCallback(Object state); -#if FEATURE_CORECLR - - [SecurityCritical] internal struct ExecutionContextSwitcher { internal ExecutionContext m_ec; @@ -48,7 +37,7 @@ namespace System.Threading internal void Undo(Thread currentThread) { - Contract.Assert(currentThread == Thread.CurrentThread); + Debug.Assert(currentThread == Thread.CurrentThread); // The common case is that these have not changed, so avoid the cost of a write if not needed. if (currentThread.SynchronizationContext != m_sc) @@ -63,32 +52,108 @@ namespace System.Threading } } - public sealed class ExecutionContext : IDisposable + [Serializable] + public sealed class ExecutionContext : IDisposable, ISerializable { private static readonly ExecutionContext Default = new ExecutionContext(); - private readonly Dictionary<IAsyncLocal, object> m_localValues; + private readonly IAsyncLocalValueMap m_localValues; private readonly IAsyncLocal[] m_localChangeNotifications; + private readonly bool m_isFlowSuppressed; private ExecutionContext() { - m_localValues = new Dictionary<IAsyncLocal, object>(); + m_localValues = AsyncLocalValueMap.Empty; m_localChangeNotifications = Array.Empty<IAsyncLocal>(); } - private ExecutionContext(Dictionary<IAsyncLocal, object> localValues, IAsyncLocal[] localChangeNotifications) + private ExecutionContext( + IAsyncLocalValueMap localValues, + IAsyncLocal[] localChangeNotifications, + bool isFlowSuppressed) { m_localValues = localValues; m_localChangeNotifications = localChangeNotifications; + m_isFlowSuppressed = isFlowSuppressed; + } + + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException(nameof(info)); + } + Contract.EndContractBlock(); + } + + private ExecutionContext(SerializationInfo info, StreamingContext context) + { } - [SecuritySafeCritical] public static ExecutionContext Capture() { - return Thread.CurrentThread.ExecutionContext ?? ExecutionContext.Default; + ExecutionContext executionContext = Thread.CurrentThread.ExecutionContext; + if (executionContext == null) + { + return Default; + } + if (executionContext.m_isFlowSuppressed) + { + // Prevent ExecutionContext.Run on a suppressed-flow context for desktop framework compatibility + return null; + } + return executionContext; + } + + private ExecutionContext ShallowClone(bool isFlowSuppressed) + { + Debug.Assert(isFlowSuppressed != m_isFlowSuppressed); + + if (!isFlowSuppressed && + m_localValues == Default.m_localValues && + m_localChangeNotifications == Default.m_localChangeNotifications) + { + return null; // implies the default context + } + return new ExecutionContext(m_localValues, m_localChangeNotifications, isFlowSuppressed); + } + + public static AsyncFlowControl SuppressFlow() + { + Thread currentThread = Thread.CurrentThread; + ExecutionContext executionContext = currentThread.ExecutionContext ?? Default; + if (executionContext.m_isFlowSuppressed) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotSupressFlowMultipleTimes")); + } + Contract.EndContractBlock(); + + executionContext = executionContext.ShallowClone(isFlowSuppressed: true); + var asyncFlowControl = new AsyncFlowControl(); + currentThread.ExecutionContext = executionContext; + asyncFlowControl.Initialize(currentThread); + return asyncFlowControl; + } + + public static void RestoreFlow() + { + Thread currentThread = Thread.CurrentThread; + ExecutionContext executionContext = currentThread.ExecutionContext; + if (executionContext == null || !executionContext.m_isFlowSuppressed) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRestoreUnsupressedFlow")); + } + Contract.EndContractBlock(); + + currentThread.ExecutionContext = executionContext.ShallowClone(isFlowSuppressed: false); + } + + public static bool IsFlowSuppressed() + { + ExecutionContext executionContext = Thread.CurrentThread.ExecutionContext; + return executionContext != null && executionContext.m_isFlowSuppressed; } - [SecurityCritical] [HandleProcessCorruptedStateExceptions] public static void Run(ExecutionContext executionContext, ContextCallback callback, Object state) { @@ -115,10 +180,9 @@ namespace System.Threading ecsw.Undo(currentThread); } - [SecurityCritical] internal static void Restore(Thread currentThread, ExecutionContext executionContext) { - Contract.Assert(currentThread == Thread.CurrentThread); + Debug.Assert(currentThread == Thread.CurrentThread); ExecutionContext previous = currentThread.ExecutionContext ?? Default; currentThread.ExecutionContext = executionContext; @@ -133,22 +197,20 @@ namespace System.Threading } } - [SecurityCritical] static internal void EstablishCopyOnWriteScope(Thread currentThread, ref ExecutionContextSwitcher ecsw) { - Contract.Assert(currentThread == Thread.CurrentThread); + Debug.Assert(currentThread == Thread.CurrentThread); ecsw.m_ec = currentThread.ExecutionContext; ecsw.m_sc = currentThread.SynchronizationContext; } - [SecurityCritical] [HandleProcessCorruptedStateExceptions] private static void OnContextChanged(ExecutionContext previous, ExecutionContext current) { - Contract.Assert(previous != null); - Contract.Assert(current != null); - Contract.Assert(previous != current); + Debug.Assert(previous != null); + Debug.Assert(current != null); + Debug.Assert(previous != current); foreach (IAsyncLocal local in previous.m_localChangeNotifications) { @@ -189,7 +251,6 @@ namespace System.Threading } } - [SecurityCritical] internal static object GetLocalValue(IAsyncLocal local) { ExecutionContext current = Thread.CurrentThread.ExecutionContext; @@ -201,7 +262,6 @@ namespace System.Threading return value; } - [SecurityCritical] internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications) { ExecutionContext current = Thread.CurrentThread.ExecutionContext ?? ExecutionContext.Default; @@ -212,16 +272,7 @@ namespace System.Threading if (previousValue == newValue) return; - // - // Allocate a new Dictionary containing a copy of the old values, plus the new value. We have to do this manually to - // minimize allocations of IEnumerators, etc. - // - Dictionary<IAsyncLocal, object> newValues = new Dictionary<IAsyncLocal, object>(current.m_localValues.Count + (hadPreviousValue ? 0 : 1)); - - foreach (KeyValuePair<IAsyncLocal, object> pair in current.m_localValues) - newValues.Add(pair.Key, pair.Value); - - newValues[local] = newValue; + IAsyncLocalValueMap newValues = current.m_localValues.Set(local, newValue); // // Either copy the change notification array, or create a new one, depending on whether we need to add a new item. @@ -231,7 +282,7 @@ namespace System.Threading { if (hadPreviousValue) { - Contract.Assert(Array.IndexOf(newChangeNotifications, local) >= 0); + Debug.Assert(Array.IndexOf(newChangeNotifications, local) >= 0); } else { @@ -241,7 +292,8 @@ namespace System.Threading } } - Thread.CurrentThread.ExecutionContext = new ExecutionContext(newValues, newChangeNotifications); + Thread.CurrentThread.ExecutionContext = + new ExecutionContext(newValues, newChangeNotifications, current.m_isFlowSuppressed); if (needChangeNotifications) { @@ -259,33 +311,28 @@ namespace System.Threading OptimizeDefaultCase = 0x02, } - [SecurityCritical] internal static ExecutionContext Capture(ref StackCrawlMark stackMark, CaptureOptions captureOptions) { return Capture(); } - [SecuritySafeCritical] [FriendAccessAllowed] internal static ExecutionContext FastCapture() { return Capture(); } - [SecurityCritical] [FriendAccessAllowed] internal static void Run(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx) { Run(executionContext, callback, state); } - [SecurityCritical] internal bool IsDefaultFTContext(bool ignoreSyncCtx) { return this == Default; } - [SecuritySafeCritical] public ExecutionContext CreateCopy() { return this; // since CoreCLR's ExecutionContext is immutable, we don't need to create copies. @@ -296,14 +343,8 @@ namespace System.Threading // For CLR compat only } - public static bool IsFlowSuppressed() - { - return false; - } - internal static ExecutionContext PreAllocatedDefault { - [SecuritySafeCritical] get { return ExecutionContext.Default; } } @@ -315,1084 +356,77 @@ namespace System.Threading #endregion } -#else // FEATURE_CORECLR - - // Legacy desktop ExecutionContext implementation - - internal struct ExecutionContextSwitcher + public struct AsyncFlowControl : IDisposable { - internal ExecutionContext.Reader outerEC; // previous EC we need to restore on Undo - internal bool outerECBelongsToScope; -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - internal SecurityContextSwitcher scsw; -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - internal Object hecsw; -#if FEATURE_IMPERSONATION - internal WindowsIdentity wi; - internal bool cachedAlwaysFlowImpersonationPolicy; - internal bool wiIsValid; -#endif - internal Thread thread; - - [System.Security.SecurityCritical] // auto-generated - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - internal bool UndoNoThrow(Thread currentThread) - { - try - { - Undo(currentThread); - } - catch - { - return false; - } - return true; - } - - [System.Security.SecurityCritical] // auto-generated - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - internal void Undo(Thread currentThread) - { - // - // Don't use an uninitialized switcher, or one that's already been used. - // - if (thread == null) - return; // Don't do anything - - Contract.Assert(Thread.CurrentThread == this.thread); - - // - // Restore the HostExecutionContext before restoring the ExecutionContext. - // -#if FEATURE_CAS_POLICY - if (hecsw != null) - HostExecutionContextSwitcher.Undo(hecsw); -#endif // FEATURE_CAS_POLICY - - // - // restore the saved Execution Context. Note that this will also restore the - // SynchronizationContext, Logical/IllogicalCallContext, etc. - // - ExecutionContext.Reader innerEC = currentThread.GetExecutionContextReader(); - currentThread.SetExecutionContext(outerEC, outerECBelongsToScope); - -#if DEBUG - try - { - currentThread.ForbidExecutionContextMutation = true; -#endif - - // - // Tell the SecurityContext to do the side-effects of restoration. - // -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - if (scsw.currSC != null) - { - // Any critical failure inside scsw will cause FailFast - scsw.Undo(); - } -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - -#if FEATURE_IMPERSONATION - if (wiIsValid) - SecurityContext.RestoreCurrentWI(outerEC, innerEC, wi, cachedAlwaysFlowImpersonationPolicy); -#endif - - thread = null; // this will prevent the switcher object being used again -#if DEBUG - } - finally - { - currentThread.ForbidExecutionContextMutation = false; - } -#endif - ExecutionContext.OnAsyncLocalContextChanged(innerEC.DangerousGetRawExecutionContext(), outerEC.DangerousGetRawExecutionContext()); - } - } - - - public struct AsyncFlowControl: IDisposable - { - private bool useEC; - private ExecutionContext _ec; -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - private SecurityContext _sc; -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK private Thread _thread; -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - [SecurityCritical] - internal void Setup(SecurityContextDisableFlow flags) - { - useEC = false; - Thread currentThread = Thread.CurrentThread; - _sc = currentThread.GetMutableExecutionContext().SecurityContext; - _sc._disableFlow = flags; - _thread = currentThread; - } -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - [SecurityCritical] - internal void Setup() + + internal void Initialize(Thread currentThread) { - useEC = true; - Thread currentThread = Thread.CurrentThread; - _ec = currentThread.GetMutableExecutionContext(); - _ec.isFlowSuppressed = true; + Debug.Assert(currentThread == Thread.CurrentThread); _thread = currentThread; } - - public void Dispose() - { - Undo(); - } - - [SecuritySafeCritical] + public void Undo() { if (_thread == null) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCMultiple")); - } - if (_thread != Thread.CurrentThread) - { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCOtherThread")); - } - if (useEC) - { - if (Thread.CurrentThread.GetMutableExecutionContext() != _ec) - { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch")); - } - ExecutionContext.RestoreFlow(); - } -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - else - { - if (!Thread.CurrentThread.GetExecutionContextReader().SecurityContext.IsSame(_sc)) - { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch")); - } - SecurityContext.RestoreFlow(); - } -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - _thread = null; - } - - public override int GetHashCode() - { - return _thread == null ? ToString().GetHashCode() : _thread.GetHashCode(); - } - - public override bool Equals(Object obj) - { - if (obj is AsyncFlowControl) - return Equals((AsyncFlowControl)obj); - else - return false; - } - - public bool Equals(AsyncFlowControl obj) - { - return obj.useEC == useEC && obj._ec == _ec && -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - obj._sc == _sc && -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - obj._thread == _thread; - } - - public static bool operator ==(AsyncFlowControl a, AsyncFlowControl b) - { - return a.Equals(b); - } - - public static bool operator !=(AsyncFlowControl a, AsyncFlowControl b) - { - return !(a == b); - } - - } - - -#if FEATURE_SERIALIZATION - [Serializable] -#endif - public sealed class ExecutionContext : IDisposable, ISerializable - { - /*========================================================================= - ** Data accessed from managed code that needs to be defined in - ** ExecutionContextObject to maintain alignment between the two classes. - ** DON'T CHANGE THESE UNLESS YOU MODIFY ExecutionContextObject in vm\object.h - =========================================================================*/ -#if FEATURE_CAS_POLICY - private HostExecutionContext _hostExecutionContext; -#endif // FEATURE_CAS_POLICY - private SynchronizationContext _syncContext; - private SynchronizationContext _syncContextNoFlow; -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - private SecurityContext _securityContext; -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK -#if FEATURE_REMOTING - [System.Security.SecurityCritical] // auto-generated - private LogicalCallContext _logicalCallContext; - private IllogicalCallContext _illogicalCallContext; // this call context follows the physical thread -#endif // #if FEATURE_REMOTING - - enum Flags - { - None = 0x0, - IsNewCapture = 0x1, - IsFlowSuppressed = 0x2, - IsPreAllocatedDefault = 0x4 - } - private Flags _flags; - - private Dictionary<IAsyncLocal, object> _localValues; - private List<IAsyncLocal> _localChangeNotifications; - - internal bool isNewCapture - { - get - { - return (_flags & (Flags.IsNewCapture | Flags.IsPreAllocatedDefault)) != Flags.None; - } - set - { - Contract.Assert(!IsPreAllocatedDefault); - if (value) - _flags |= Flags.IsNewCapture; - else - _flags &= ~Flags.IsNewCapture; - } - } - internal bool isFlowSuppressed - { - get - { - return (_flags & Flags.IsFlowSuppressed) != Flags.None; - } - set - { - Contract.Assert(!IsPreAllocatedDefault); - if (value) - _flags |= Flags.IsFlowSuppressed; - else - _flags &= ~Flags.IsFlowSuppressed; - } - } - - - private static readonly ExecutionContext s_dummyDefaultEC = new ExecutionContext(isPreAllocatedDefault: true); - - static internal ExecutionContext PreAllocatedDefault - { - [SecuritySafeCritical] - get { return s_dummyDefaultEC; } - } - - internal bool IsPreAllocatedDefault - { - get - { - // we use _flags instead of a direct comparison w/ s_dummyDefaultEC to avoid the static access on - // hot code paths. - if ((_flags & Flags.IsPreAllocatedDefault) != Flags.None) - { - Contract.Assert(this == s_dummyDefaultEC); - return true; - } - else - { - return false; - } - } - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - internal ExecutionContext() - { - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - internal ExecutionContext(bool isPreAllocatedDefault) - { - if (isPreAllocatedDefault) - _flags = Flags.IsPreAllocatedDefault; - } - - // Read-only wrapper around ExecutionContext. This enables safe reading of an ExecutionContext without accidentally modifying it. - internal struct Reader - { - ExecutionContext m_ec; - - public Reader(ExecutionContext ec) { m_ec = ec; } - - public ExecutionContext DangerousGetRawExecutionContext() { return m_ec; } - - public bool IsNull { get { return m_ec == null; } } - [SecurityCritical] - public bool IsDefaultFTContext(bool ignoreSyncCtx) { return m_ec.IsDefaultFTContext(ignoreSyncCtx); } - public bool IsFlowSuppressed - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return IsNull ? false : m_ec.isFlowSuppressed; } - } - //public Thread Thread { get { return m_ec._thread; } } - public bool IsSame(ExecutionContext.Reader other) { return m_ec == other.m_ec; } - - public SynchronizationContext SynchronizationContext { get { return IsNull ? null : m_ec.SynchronizationContext; } } - public SynchronizationContext SynchronizationContextNoFlow { get { return IsNull ? null : m_ec.SynchronizationContextNoFlow; } } - -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - public SecurityContext.Reader SecurityContext - { - [SecurityCritical] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return new SecurityContext.Reader(IsNull ? null : m_ec.SecurityContext); } - } -#endif - -#if FEATURE_REMOTING - public LogicalCallContext.Reader LogicalCallContext - { - [SecurityCritical] - get { return new LogicalCallContext.Reader(IsNull ? null : m_ec.LogicalCallContext); } - } - - public IllogicalCallContext.Reader IllogicalCallContext - { - [SecurityCritical] - get { return new IllogicalCallContext.Reader(IsNull ? null : m_ec.IllogicalCallContext); } - } -#endif - - [SecurityCritical] - public object GetLocalValue(IAsyncLocal local) - { - if (IsNull) - return null; - - if (m_ec._localValues == null) - return null; - - object value; - m_ec._localValues.TryGetValue(local, out value); - return value; - } - - [SecurityCritical] - public bool HasSameLocalValues(ExecutionContext other) - { - var thisLocalValues = IsNull ? null : m_ec._localValues; - var otherLocalValues = other == null ? null : other._localValues; - return thisLocalValues == otherLocalValues; - } - - [SecurityCritical] - public bool HasLocalValues() - { - return !this.IsNull && m_ec._localValues != null; - } - } - - [SecurityCritical] - internal static object GetLocalValue(IAsyncLocal local) - { - return Thread.CurrentThread.GetExecutionContextReader().GetLocalValue(local); - } - - [SecurityCritical] - internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications) - { - ExecutionContext current = Thread.CurrentThread.GetMutableExecutionContext(); - - object previousValue = null; - bool hadPreviousValue = current._localValues != null && current._localValues.TryGetValue(local, out previousValue); - - if (previousValue == newValue) - return; - - if (current._localValues == null) - current._localValues = new Dictionary<IAsyncLocal, object>(); - else - current._localValues = new Dictionary<IAsyncLocal, object>(current._localValues); - - current._localValues[local] = newValue; - - if (needChangeNotifications) - { - if (hadPreviousValue) - { - Contract.Assert(current._localChangeNotifications != null); - Contract.Assert(current._localChangeNotifications.Contains(local)); - } - else - { - if (current._localChangeNotifications == null) - current._localChangeNotifications = new List<IAsyncLocal>(); - else - current._localChangeNotifications = new List<IAsyncLocal>(current._localChangeNotifications); - - current._localChangeNotifications.Add(local); - } - - local.OnValueChanged(previousValue, newValue, false); - } - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static void OnAsyncLocalContextChanged(ExecutionContext previous, ExecutionContext current) - { - List<IAsyncLocal> previousLocalChangeNotifications = (previous == null) ? null : previous._localChangeNotifications; - if (previousLocalChangeNotifications != null) - { - foreach (IAsyncLocal local in previousLocalChangeNotifications) - { - object previousValue = null; - if (previous != null && previous._localValues != null) - previous._localValues.TryGetValue(local, out previousValue); - - object currentValue = null; - if (current != null && current._localValues != null) - current._localValues.TryGetValue(local, out currentValue); - - if (previousValue != currentValue) - local.OnValueChanged(previousValue, currentValue, true); - } - } - - List<IAsyncLocal> currentLocalChangeNotifications = (current == null) ? null : current._localChangeNotifications; - if (currentLocalChangeNotifications != null && currentLocalChangeNotifications != previousLocalChangeNotifications) - { - try - { - foreach (IAsyncLocal local in currentLocalChangeNotifications) - { - // If the local has a value in the previous context, we already fired the event for that local - // in the code above. - object previousValue = null; - if (previous == null || - previous._localValues == null || - !previous._localValues.TryGetValue(local, out previousValue)) - { - object currentValue = null; - if (current != null && current._localValues != null) - current._localValues.TryGetValue(local, out currentValue); - - if (previousValue != currentValue) - local.OnValueChanged(previousValue, currentValue, true); - } - } - } - catch (Exception ex) - { - Environment.FailFast( - Environment.GetResourceString("ExecutionContext_ExceptionInAsyncLocalNotification"), - ex); - } - } - } - - -#if FEATURE_REMOTING - internal LogicalCallContext LogicalCallContext - { - [System.Security.SecurityCritical] // auto-generated - get - { - if (_logicalCallContext == null) - { - _logicalCallContext = new LogicalCallContext(); - } - return _logicalCallContext; - } - [System.Security.SecurityCritical] // auto-generated - set - { - Contract.Assert(this != s_dummyDefaultEC); - _logicalCallContext = value; - } - } - - internal IllogicalCallContext IllogicalCallContext - { - get - { - if (_illogicalCallContext == null) - { - _illogicalCallContext = new IllogicalCallContext(); - } - return _illogicalCallContext; - } - set - { - Contract.Assert(this != s_dummyDefaultEC); - _illogicalCallContext = value; - } - } -#endif // #if FEATURE_REMOTING - - internal SynchronizationContext SynchronizationContext - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - get - { - return _syncContext; - } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - set - { - Contract.Assert(this != s_dummyDefaultEC); - _syncContext = value; - } - } - - internal SynchronizationContext SynchronizationContextNoFlow - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - get - { - return _syncContextNoFlow; - } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - set - { - Contract.Assert(this != s_dummyDefaultEC); - _syncContextNoFlow = value; - } - } - -#if FEATURE_CAS_POLICY - internal HostExecutionContext HostExecutionContext - { - get - { - return _hostExecutionContext; } - set + if (Thread.CurrentThread != _thread) { - Contract.Assert(this != s_dummyDefaultEC); - _hostExecutionContext = value; - } - } -#endif // FEATURE_CAS_POLICY -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - internal SecurityContext SecurityContext - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - get - { - return _securityContext; - } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - set - { - Contract.Assert(this != s_dummyDefaultEC); - // store the new security context - _securityContext = value; - // perform the reverse link too - if (value != null) - _securityContext.ExecutionContext = this; - } - } -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - - - public void Dispose() - { - if(this.IsPreAllocatedDefault) - return; //Do nothing if this is the default context -#if FEATURE_CAS_POLICY - if (_hostExecutionContext != null) - _hostExecutionContext.Dispose(); -#endif // FEATURE_CAS_POLICY -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - if (_securityContext != null) - _securityContext.Dispose(); -#endif //FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - } - - [DynamicSecurityMethod] - [System.Security.SecurityCritical] // auto-generated_required - public static void Run(ExecutionContext executionContext, ContextCallback callback, Object state) - { - if (executionContext == null) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NullContext")); - if (!executionContext.isNewCapture) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotNewCaptureContext")); - - Run(executionContext, callback, state, false); - } - - // This method is special from a security perspective - the VM will not allow a stack walk to - // continue past the call to ExecutionContext.Run. If you change the signature to this method, make - // sure to update SecurityStackWalk::IsSpecialRunFrame in the VM to search for the new signature. - [DynamicSecurityMethod] - [SecurityCritical] - [FriendAccessAllowed] - internal static void Run(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx) - { - RunInternal(executionContext, callback, state, preserveSyncCtx); - } - - // Actual implementation of Run is here, in a non-DynamicSecurityMethod, because the JIT seems to refuse to inline callees into - // a DynamicSecurityMethod. - [SecurityCritical] - [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread safety")] - [HandleProcessCorruptedStateExceptions] - internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx) - { - Contract.Assert(executionContext != null); - if (executionContext.IsPreAllocatedDefault) - { - Contract.Assert(executionContext.IsDefaultFTContext(preserveSyncCtx)); - } - else - { - Contract.Assert(executionContext.isNewCapture); - executionContext.isNewCapture = false; - } - - Thread currentThread = Thread.CurrentThread; - ExecutionContextSwitcher ecsw = default(ExecutionContextSwitcher); - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - ExecutionContext.Reader ec = currentThread.GetExecutionContextReader(); - if ( (ec.IsNull || ec.IsDefaultFTContext(preserveSyncCtx)) && - #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - SecurityContext.CurrentlyInDefaultFTSecurityContext(ec) && - #endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - executionContext.IsDefaultFTContext(preserveSyncCtx) && - ec.HasSameLocalValues(executionContext) - ) - { - // Neither context is interesting, so we don't need to set the context. - // We do need to reset any changes made by the user's callback, - // so here we establish a "copy-on-write scope". Any changes will - // result in a copy of the context being made, preserving the original - // context. - EstablishCopyOnWriteScope(currentThread, true, ref ecsw); - } - else - { - if (executionContext.IsPreAllocatedDefault) - executionContext = new ExecutionContext(); - ecsw = SetExecutionContext(executionContext, preserveSyncCtx); - } - - // - // Call the user's callback - // - callback(state); - } - finally - { - ecsw.Undo(currentThread); - } - } - - [SecurityCritical] - static internal void EstablishCopyOnWriteScope(Thread currentThread, ref ExecutionContextSwitcher ecsw) - { - EstablishCopyOnWriteScope(currentThread, false, ref ecsw); - } - - [SecurityCritical] - static private void EstablishCopyOnWriteScope(Thread currentThread, bool knownNullWindowsIdentity, ref ExecutionContextSwitcher ecsw) - { - Contract.Assert(currentThread == Thread.CurrentThread); - - ecsw.outerEC = currentThread.GetExecutionContextReader(); - ecsw.outerECBelongsToScope = currentThread.ExecutionContextBelongsToCurrentScope; - -#if FEATURE_IMPERSONATION - ecsw.cachedAlwaysFlowImpersonationPolicy = SecurityContext.AlwaysFlowImpersonationPolicy; - if (knownNullWindowsIdentity) - Contract.Assert(SecurityContext.GetCurrentWI(ecsw.outerEC, ecsw.cachedAlwaysFlowImpersonationPolicy) == null); - else - ecsw.wi = SecurityContext.GetCurrentWI(ecsw.outerEC, ecsw.cachedAlwaysFlowImpersonationPolicy); - ecsw.wiIsValid = true; -#endif - currentThread.ExecutionContextBelongsToCurrentScope = false; - ecsw.thread = currentThread; - } - - - // Sets the given execution context object on the thread. - // Returns the previous one. - [System.Security.SecurityCritical] // auto-generated - [DynamicSecurityMethodAttribute()] - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - internal static ExecutionContextSwitcher SetExecutionContext(ExecutionContext executionContext, bool preserveSyncCtx) - { -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - - Contract.Assert(executionContext != null); - Contract.Assert(executionContext != s_dummyDefaultEC); - - // Set up the switcher object to return; - ExecutionContextSwitcher ecsw = new ExecutionContextSwitcher(); - - Thread currentThread = Thread.CurrentThread; - ExecutionContext.Reader outerEC = currentThread.GetExecutionContextReader(); - - ecsw.thread = currentThread; - ecsw.outerEC = outerEC; - ecsw.outerECBelongsToScope = currentThread.ExecutionContextBelongsToCurrentScope; - - if (preserveSyncCtx) - executionContext.SynchronizationContext = outerEC.SynchronizationContext; - executionContext.SynchronizationContextNoFlow = outerEC.SynchronizationContextNoFlow; - - currentThread.SetExecutionContext(executionContext, belongsToCurrentScope: true); - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - OnAsyncLocalContextChanged(outerEC.DangerousGetRawExecutionContext(), executionContext); - -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - //set the security context - SecurityContext sc = executionContext.SecurityContext; - if (sc != null) - { - // non-null SC: needs to be set - SecurityContext.Reader prevSeC = outerEC.SecurityContext; - ecsw.scsw = SecurityContext.SetSecurityContext(sc, prevSeC, false, ref stackMark); - } - else if (!SecurityContext.CurrentlyInDefaultFTSecurityContext(ecsw.outerEC)) - { - // null incoming SC, but we're currently not in FT: use static FTSC to set - SecurityContext.Reader prevSeC = outerEC.SecurityContext; - ecsw.scsw = SecurityContext.SetSecurityContext(SecurityContext.FullTrustSecurityContext, prevSeC, false, ref stackMark); - } -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK -#if FEATURE_CAS_POLICY - // set the Host Context - HostExecutionContext hostContext = executionContext.HostExecutionContext; - if (hostContext != null) - { - ecsw.hecsw = HostExecutionContextManager.SetHostExecutionContextInternal(hostContext); - } -#endif // FEATURE_CAS_POLICY - } - catch - { - ecsw.UndoNoThrow(currentThread); - throw; - } - return ecsw; - } - - // - // Public CreateCopy. Used to copy captured ExecutionContexts so they can be reused multiple times. - // This should only copy the portion of the context that we actually capture. - // - [SecuritySafeCritical] - public ExecutionContext CreateCopy() - { - if (!isNewCapture) - { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotCopyUsedContext")); - } - ExecutionContext ec = new ExecutionContext(); - ec.isNewCapture = true; - ec._syncContext = _syncContext == null ? null : _syncContext.CreateCopy(); - ec._localValues = _localValues; - ec._localChangeNotifications = _localChangeNotifications; -#if FEATURE_CAS_POLICY - // capture the host execution context - ec._hostExecutionContext = _hostExecutionContext == null ? null : _hostExecutionContext.CreateCopy(); -#endif // FEATURE_CAS_POLICY -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - if (_securityContext != null) - { - ec._securityContext = _securityContext.CreateCopy(); - ec._securityContext.ExecutionContext = ec; + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCOtherThread")); } -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - -#if FEATURE_REMOTING - if (this._logicalCallContext != null) - ec.LogicalCallContext = (LogicalCallContext)this.LogicalCallContext.Clone(); - - Contract.Assert(this._illogicalCallContext == null); -#endif // #if FEATURE_REMOTING - - return ec; - } - - // - // Creates a complete copy, used for copy-on-write. - // - [SecuritySafeCritical] - internal ExecutionContext CreateMutableCopy() - { - Contract.Assert(!this.isNewCapture); - - ExecutionContext ec = new ExecutionContext(); - // We don't deep-copy the SyncCtx, since we're still in the same context after copy-on-write. - ec._syncContext = this._syncContext; - ec._syncContextNoFlow = this._syncContextNoFlow; - -#if FEATURE_CAS_POLICY - // capture the host execution context - ec._hostExecutionContext = this._hostExecutionContext == null ? null : _hostExecutionContext.CreateCopy(); -#endif // FEATURE_CAS_POLICY - -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - if (_securityContext != null) + // An async flow control cannot be undone when a different execution context is applied. The desktop framework + // mutates the execution context when its state changes, and only changes the instance when an execution context + // is applied (for instance, through ExecutionContext.Run). The framework prevents a suppressed-flow execution + // context from being applied by returning null from ExecutionContext.Capture, so the only type of execution + // context that can be applied is one whose flow is not suppressed. After suppressing flow and changing an async + // local's value, the desktop framework verifies that a different execution context has not been applied by + // checking the execution context instance against the one saved from when flow was suppressed. In .NET Core, + // since the execution context instance will change after changing the async local's value, it verifies that a + // different execution context has not been applied, by instead ensuring that the current execution context's + // flow is suppressed. + if (!ExecutionContext.IsFlowSuppressed()) { - ec._securityContext = this._securityContext.CreateMutableCopy(); - ec._securityContext.ExecutionContext = ec; - } -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - -#if FEATURE_REMOTING - if (this._logicalCallContext != null) - ec.LogicalCallContext = (LogicalCallContext)this.LogicalCallContext.Clone(); - - if (this._illogicalCallContext != null) - ec.IllogicalCallContext = (IllogicalCallContext)this.IllogicalCallContext.CreateCopy(); -#endif // #if FEATURE_REMOTING - - ec._localValues = this._localValues; - ec._localChangeNotifications = this._localChangeNotifications; - ec.isFlowSuppressed = this.isFlowSuppressed; - - return ec; - } - - [System.Security.SecurityCritical] // auto-generated_required - public static AsyncFlowControl SuppressFlow() - { - if (IsFlowSuppressed()) - { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotSupressFlowMultipleTimes")); + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch")); } Contract.EndContractBlock(); - AsyncFlowControl afc = new AsyncFlowControl(); - afc.Setup(); - return afc; - } - - [SecuritySafeCritical] - public static void RestoreFlow() - { - ExecutionContext ec = Thread.CurrentThread.GetMutableExecutionContext(); - if (!ec.isFlowSuppressed) - { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRestoreUnsupressedFlow")); - } - ec.isFlowSuppressed = false; - } - [Pure] - public static bool IsFlowSuppressed() - { - return Thread.CurrentThread.GetExecutionContextReader().IsFlowSuppressed; + _thread = null; + ExecutionContext.RestoreFlow(); } - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public static ExecutionContext Capture() + public void Dispose() { - // set up a stack mark for finding the caller - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return ExecutionContext.Capture(ref stackMark, CaptureOptions.None); + Undo(); } - // - // Captures an ExecutionContext with optimization for the "default" case, and captures a "null" synchronization context. - // When calling ExecutionContext.Run on the returned context, specify ignoreSyncCtx = true - // - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - [FriendAccessAllowed] - internal static ExecutionContext FastCapture() + public override bool Equals(object obj) { - // set up a stack mark for finding the caller - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return ExecutionContext.Capture(ref stackMark, CaptureOptions.IgnoreSyncCtx | CaptureOptions.OptimizeDefaultCase); + return obj is AsyncFlowControl && Equals((AsyncFlowControl)obj); } - - [Flags] - internal enum CaptureOptions + public bool Equals(AsyncFlowControl obj) { - None = 0x00, - - IgnoreSyncCtx = 0x01, //Don't flow SynchronizationContext - - OptimizeDefaultCase = 0x02, //Faster in the typical case, but can't show the result to users - // because they could modify the shared default EC. - // Use this only if you won't be exposing the captured EC to users. + return _thread == obj._thread; } - // internal helper to capture the current execution context using a passed in stack mark - [System.Security.SecurityCritical] // auto-generated - static internal ExecutionContext Capture(ref StackCrawlMark stackMark, CaptureOptions options) + public override int GetHashCode() { - ExecutionContext.Reader ecCurrent = Thread.CurrentThread.GetExecutionContextReader(); - - // check to see if Flow is suppressed - if (ecCurrent.IsFlowSuppressed) - return null; - - // - // Attempt to capture context. There may be nothing to capture... - // - -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - // capture the security context - SecurityContext secCtxNew = SecurityContext.Capture(ecCurrent, ref stackMark); -#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK -#if FEATURE_CAS_POLICY - // capture the host execution context - HostExecutionContext hostCtxNew = HostExecutionContextManager.CaptureHostExecutionContext(); -#endif // FEATURE_CAS_POLICY - - SynchronizationContext syncCtxNew = null; - -#if FEATURE_REMOTING - LogicalCallContext logCtxNew = null; -#endif - - if (!ecCurrent.IsNull) - { - // capture the sync context - if (0 == (options & CaptureOptions.IgnoreSyncCtx)) - syncCtxNew = (ecCurrent.SynchronizationContext == null) ? null : ecCurrent.SynchronizationContext.CreateCopy(); - -#if FEATURE_REMOTING - // copy over the Logical Call Context - if (ecCurrent.LogicalCallContext.HasInfo) - logCtxNew = ecCurrent.LogicalCallContext.Clone(); -#endif // #if FEATURE_REMOTING - } - - Dictionary<IAsyncLocal, object> localValues = null; - List<IAsyncLocal> localChangeNotifications = null; - if (!ecCurrent.IsNull) - { - localValues = ecCurrent.DangerousGetRawExecutionContext()._localValues; - localChangeNotifications = ecCurrent.DangerousGetRawExecutionContext()._localChangeNotifications; - } - - // - // If we didn't get anything but defaults, and we're allowed to return the - // dummy default EC, don't bother allocating a new context. - // - if (0 != (options & CaptureOptions.OptimizeDefaultCase) && -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - secCtxNew == null && -#endif -#if FEATURE_CAS_POLICY - hostCtxNew == null && -#endif // FEATURE_CAS_POLICY - syncCtxNew == null && -#if FEATURE_REMOTING - (logCtxNew == null || !logCtxNew.HasInfo) && -#endif // #if FEATURE_REMOTING - localValues == null && - localChangeNotifications == null - ) - { - return s_dummyDefaultEC; - } - - // - // Allocate the new context, and fill it in. - // - ExecutionContext ecNew = new ExecutionContext(); -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - ecNew.SecurityContext = secCtxNew; - if (ecNew.SecurityContext != null) - ecNew.SecurityContext.ExecutionContext = ecNew; -#endif -#if FEATURE_CAS_POLICY - ecNew._hostExecutionContext = hostCtxNew; -#endif // FEATURE_CAS_POLICY - ecNew._syncContext = syncCtxNew; -#if FEATURE_REMOTING - ecNew.LogicalCallContext = logCtxNew; -#endif // #if FEATURE_REMOTING - ecNew._localValues = localValues; - ecNew._localChangeNotifications = localChangeNotifications; - ecNew.isNewCapture = true; - - return ecNew; + return _thread?.GetHashCode() ?? 0; } - // - // Implementation of ISerializable - // - - [System.Security.SecurityCritical] // auto-generated_required - public void GetObjectData(SerializationInfo info, StreamingContext context) + public static bool operator ==(AsyncFlowControl a, AsyncFlowControl b) { - if (info==null) - throw new ArgumentNullException("info"); - Contract.EndContractBlock(); - -#if FEATURE_REMOTING - if (_logicalCallContext != null) - { - info.AddValue("LogicalCallContext", _logicalCallContext, typeof(LogicalCallContext)); - } -#endif // #if FEATURE_REMOTING + return a.Equals(b); } - [System.Security.SecurityCritical] // auto-generated - private ExecutionContext(SerializationInfo info, StreamingContext context) - { - SerializationInfoEnumerator e = info.GetEnumerator(); - while (e.MoveNext()) - { -#if FEATURE_REMOTING - if (e.Name.Equals("LogicalCallContext")) - { - _logicalCallContext = (LogicalCallContext) e.Value; - } -#endif // #if FEATURE_REMOTING - } - } // ObjRef .ctor - - - [System.Security.SecurityCritical] // auto-generated - internal bool IsDefaultFTContext(bool ignoreSyncCtx) + public static bool operator !=(AsyncFlowControl a, AsyncFlowControl b) { -#if FEATURE_CAS_POLICY - if (_hostExecutionContext != null) - return false; -#endif // FEATURE_CAS_POLICY - if (!ignoreSyncCtx && _syncContext != null) - return false; -#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK - if (_securityContext != null && !_securityContext.IsDefaultFTSecurityContext()) - return false; -#endif //#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK -#if FEATURE_REMOTING - if (_logicalCallContext != null && _logicalCallContext.HasInfo) - return false; - if (_illogicalCallContext != null && _illogicalCallContext.HasUserData) - return false; -#endif //#if FEATURE_REMOTING - return true; + return !(a == b); } - } // class ExecutionContext - -#endif //FEATURE_CORECLR + } } diff --git a/src/mscorlib/src/System/Threading/Interlocked.cs b/src/mscorlib/src/System/Threading/Interlocked.cs index 50cc766d61..8a0b527fc0 100644 --- a/src/mscorlib/src/System/Threading/Interlocked.cs +++ b/src/mscorlib/src/System/Threading/Interlocked.cs @@ -66,34 +66,27 @@ namespace System.Threading [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [System.Security.SecuritySafeCritical] public static extern int Exchange(ref int location1, int value); [MethodImplAttribute(MethodImplOptions.InternalCall)] - [System.Security.SecuritySafeCritical] public static extern long Exchange(ref long location1, long value); [MethodImplAttribute(MethodImplOptions.InternalCall)] - [System.Security.SecuritySafeCritical] public static extern float Exchange(ref float location1, float value); [MethodImplAttribute(MethodImplOptions.InternalCall)] - [System.Security.SecuritySafeCritical] public static extern double Exchange(ref double location1, double value); [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [System.Security.SecuritySafeCritical] public static extern Object Exchange(ref Object location1, Object value); [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [System.Security.SecuritySafeCritical] public static extern IntPtr Exchange(ref IntPtr location1, IntPtr value); [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [System.Runtime.InteropServices.ComVisible(false)] - [System.Security.SecuritySafeCritical] public static T Exchange<T>(ref T location1, T value) where T : class { _Exchange(__makeref(location1), __makeref(value)); @@ -106,7 +99,6 @@ namespace System.Threading [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [System.Security.SecuritySafeCritical] private static extern void _Exchange(TypedReference location1, TypedReference value); /****************************** @@ -121,29 +113,23 @@ namespace System.Threading [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [System.Security.SecuritySafeCritical] public static extern int CompareExchange(ref int location1, int value, int comparand); [MethodImplAttribute(MethodImplOptions.InternalCall)] - [System.Security.SecuritySafeCritical] public static extern long CompareExchange(ref long location1, long value, long comparand); [MethodImplAttribute(MethodImplOptions.InternalCall)] - [System.Security.SecuritySafeCritical] public static extern float CompareExchange(ref float location1, float value, float comparand); [MethodImplAttribute(MethodImplOptions.InternalCall)] - [System.Security.SecuritySafeCritical] public static extern double CompareExchange(ref double location1, double value, double comparand); [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [System.Security.SecuritySafeCritical] public static extern Object CompareExchange(ref Object location1, Object value, Object comparand); [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [System.Security.SecuritySafeCritical] public static extern IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr comparand); /***************************************************************** @@ -172,7 +158,6 @@ namespace System.Threading [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [System.Runtime.InteropServices.ComVisible(false)] - [System.Security.SecuritySafeCritical] public static T CompareExchange<T>(ref T location1, T value, T comparand) where T : class { // _CompareExchange() passes back the value read from location1 via local named 'value' @@ -182,13 +167,11 @@ namespace System.Threading [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [System.Security.SecuritySafeCritical] private static extern void _CompareExchange(TypedReference location1, TypedReference value, Object comparand); // BCL-internal overload that returns success via a ref bool param, useful for reliable spin locks. [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [System.Security.SecuritySafeCritical] internal static extern int CompareExchange(ref int location1, int value, int comparand, ref bool succeeded); /****************************** diff --git a/src/mscorlib/src/System/Threading/LazyInitializer.cs b/src/mscorlib/src/System/Threading/LazyInitializer.cs index c8e74e30e3..238cc89dbd 100644 --- a/src/mscorlib/src/System/Threading/LazyInitializer.cs +++ b/src/mscorlib/src/System/Threading/LazyInitializer.cs @@ -12,6 +12,7 @@ using System.Security.Permissions; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace System.Threading { @@ -54,7 +55,6 @@ namespace System.Threading /// These routines avoid needing to allocate a dedicated, lazy-initialization instance, instead using /// references to ensure targets have been initialized as they are accessed. /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public static class LazyInitializer { /// <summary> @@ -149,7 +149,7 @@ namespace System.Threading } Interlocked.CompareExchange(ref target, value, null); - Contract.Assert(target != null); + Debug.Assert(target != null); return target; } diff --git a/src/mscorlib/src/System/Threading/LockRecursionException.cs b/src/mscorlib/src/System/Threading/LockRecursionException.cs index c5e3146cbc..ab95e70c7e 100644 --- a/src/mscorlib/src/System/Threading/LockRecursionException.cs +++ b/src/mscorlib/src/System/Threading/LockRecursionException.cs @@ -20,9 +20,6 @@ namespace System.Threading [Serializable] [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] -#if !FEATURE_CORECLR - [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")] -#endif public class LockRecursionException : System.Exception { public LockRecursionException() { } diff --git a/src/mscorlib/src/System/Threading/ManualResetEvent.cs b/src/mscorlib/src/System/Threading/ManualResetEvent.cs index 504cfb423c..00041567df 100644 --- a/src/mscorlib/src/System/Threading/ManualResetEvent.cs +++ b/src/mscorlib/src/System/Threading/ManualResetEvent.cs @@ -17,7 +17,6 @@ namespace System.Threading { using System.Security.Permissions; using System.Runtime.InteropServices; - [HostProtection(Synchronization=true, ExternalThreading=true)] [System.Runtime.InteropServices.ComVisible(true)] public sealed class ManualResetEvent : EventWaitHandle { diff --git a/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs b/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs index b6114ef917..509af5bfa0 100644 --- a/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs +++ b/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs @@ -13,10 +13,10 @@ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; -using System.Diagnostics; using System.Security.Permissions; using System.Threading; using System.Runtime.InteropServices; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace System.Threading @@ -47,7 +47,6 @@ namespace System.Threading /// </remarks> [ComVisible(false)] [DebuggerDisplay("Set = {IsSet}")] - [HostProtection(Synchronization = true, ExternalThreading = true)] public class ManualResetEventSlim : IDisposable { // These are the default spin counts we use on single-proc and MP machines. @@ -144,8 +143,8 @@ namespace System.Threading private set { - Contract.Assert(value >= 0, "SpinCount is a restricted-width integer. The value supplied is outside the legal range."); - Contract.Assert(value <= SpinCountState_MaxValue, "SpinCount is a restricted-width integer. The value supplied is outside the legal range."); + Debug.Assert(value >= 0, "SpinCount is a restricted-width integer. The value supplied is outside the legal range."); + Debug.Assert(value <= SpinCountState_MaxValue, "SpinCount is a restricted-width integer. The value supplied is outside the legal range."); // Don't worry about thread safety because it's set one time from the constructor m_combinedState = (m_combinedState & ~SpinCountState_BitMask) | (value << SpinCountState_ShiftCount); } @@ -164,7 +163,7 @@ namespace System.Threading set { //setting to <0 would indicate an internal flaw, hence Assert is appropriate. - Contract.Assert(value >= 0, "NumWaiters should never be less than zero. This indicates an internal error."); + Debug.Assert(value >= 0, "NumWaiters should never be less than zero. This indicates an internal error."); // it is possible for the max number of waiters to be exceeded via user-code, hence we use a real exception here. if (value >= NumWaitersState_MaxValue) @@ -218,13 +217,13 @@ namespace System.Threading { if (spinCount < 0) { - throw new ArgumentOutOfRangeException("spinCount"); + throw new ArgumentOutOfRangeException(nameof(spinCount)); } if (spinCount > SpinCountState_MaxValue) { throw new ArgumentOutOfRangeException( - "spinCount", + nameof(spinCount), String.Format(Environment.GetResourceString("ManualResetEventSlim_ctor_SpinCountOutOfRange"), SpinCountState_MaxValue)); } @@ -242,8 +241,8 @@ namespace System.Threading this.m_combinedState = initialState ? (1 << SignalledState_ShiftCount) : 0; //the spinCount argument has been validated by the ctors. //but we now sanity check our predefined constants. - Contract.Assert(DEFAULT_SPIN_SP >= 0, "Internal error - DEFAULT_SPIN_SP is outside the legal range."); - Contract.Assert(DEFAULT_SPIN_SP <= SpinCountState_MaxValue, "Internal error - DEFAULT_SPIN_SP is outside the legal range."); + Debug.Assert(DEFAULT_SPIN_SP >= 0, "Internal error - DEFAULT_SPIN_SP is outside the legal range."); + Debug.Assert(DEFAULT_SPIN_SP <= SpinCountState_MaxValue, "Internal error - DEFAULT_SPIN_SP is outside the legal range."); SpinCount = PlatformHelper.IsSingleProcessor ? DEFAULT_SPIN_SP : spinCount; @@ -295,7 +294,7 @@ namespace System.Threading bool currentIsSet = IsSet; if (currentIsSet != preInitializeIsSet) { - Contract.Assert(currentIsSet, + Debug.Assert(currentIsSet, "The only safe concurrent transition is from unset->set: detected set->unset."); // We saw it as unsignaled, but it has since become set. @@ -337,7 +336,7 @@ namespace System.Threading // If there are waiting threads, we need to pulse them. if (Waiters > 0) { - Contract.Assert(m_lock != null); //if waiters>0, then m_lock has already been created. + Debug.Assert(m_lock != null); //if waiters>0, then m_lock has already been created. lock (m_lock) { @@ -464,7 +463,7 @@ namespace System.Threading long totalMilliseconds = (long)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException("timeout"); + throw new ArgumentOutOfRangeException(nameof(timeout)); } return Wait((int)totalMilliseconds, new CancellationToken()); @@ -495,7 +494,7 @@ namespace System.Threading long totalMilliseconds = (long)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException("timeout"); + throw new ArgumentOutOfRangeException(nameof(timeout)); } return Wait((int)totalMilliseconds, cancellationToken); @@ -544,7 +543,7 @@ namespace System.Threading if (millisecondsTimeout < -1) { - throw new ArgumentOutOfRangeException("millisecondsTimeout"); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); } if (!IsSet) @@ -738,8 +737,8 @@ namespace System.Threading private static void CancellationTokenCallback(object obj) { ManualResetEventSlim mre = obj as ManualResetEventSlim; - Contract.Assert(mre != null, "Expected a ManualResetEventSlim"); - Contract.Assert(mre.m_lock != null); //the lock should have been created before this callback is registered for use. + Debug.Assert(mre != null, "Expected a ManualResetEventSlim"); + Debug.Assert(mre.m_lock != null); //the lock should have been created before this callback is registered for use. lock (mre.m_lock) { Monitor.PulseAll(mre.m_lock); // awaken all waiters @@ -759,7 +758,7 @@ namespace System.Threading { SpinWait sw = new SpinWait(); - Contract.Assert((newBits | updateBitsMask) == updateBitsMask, "newBits do not fall within the updateBitsMask."); + Debug.Assert((newBits | updateBitsMask) == updateBitsMask, "newBits do not fall within the updateBitsMask."); do { diff --git a/src/mscorlib/src/System/Threading/Monitor.cs b/src/mscorlib/src/System/Threading/Monitor.cs index 415948b425..94dec13d05 100644 --- a/src/mscorlib/src/System/Threading/Monitor.cs +++ b/src/mscorlib/src/System/Threading/Monitor.cs @@ -24,9 +24,9 @@ namespace System.Threading { using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.Versioning; + using System.Diagnostics; using System.Diagnostics.Contracts; - [HostProtection(Synchronization=true, ExternalThreading=true)] [System.Runtime.InteropServices.ComVisible(true)] public static class Monitor { @@ -38,7 +38,6 @@ namespace System.Threading { ** ** Exceptions: ArgumentNullException if object is null. =========================================================================*/ - [System.Security.SecuritySafeCritical] [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern void Enter(Object obj); @@ -54,7 +53,7 @@ namespace System.Threading { ThrowLockTakenException(); ReliableEnter(obj, ref lockTaken); - Contract.Assert(lockTaken); + Debug.Assert(lockTaken); } private static void ThrowLockTakenException() @@ -62,7 +61,6 @@ namespace System.Threading { throw new ArgumentException(Environment.GetResourceString("Argument_MustBeFalse"), "lockTaken"); } - [System.Security.SecuritySafeCritical] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void ReliableEnter(Object obj, ref bool lockTaken); @@ -77,7 +75,6 @@ namespace System.Threading { ** SynchronizationLockException if the current thread does not ** own the lock. =========================================================================*/ - [System.Security.SecuritySafeCritical] [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public static extern void Exit(Object obj); @@ -127,7 +124,7 @@ namespace System.Threading { { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long)Int32.MaxValue) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); return (int)tm; } @@ -154,20 +151,17 @@ namespace System.Threading { ReliableEnterTimeout(obj, MillisecondsTimeoutFromTimeSpan(timeout), ref lockTaken); } - [System.Security.SecuritySafeCritical] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void ReliableEnterTimeout(Object obj, int timeout, ref bool lockTaken); - [System.Security.SecuritySafeCritical] public static bool IsEntered(object obj) { if (obj == null) - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); return IsEnteredNative(obj); } - [System.Security.SecurityCritical] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool IsEnteredNative(Object obj); @@ -182,15 +176,13 @@ namespace System.Threading { ** ** Exceptions: ArgumentNullException if object is null. ========================================================================*/ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool ObjWait(bool exitContext, int millisecondsTimeout, Object obj); - [System.Security.SecuritySafeCritical] // auto-generated public static bool Wait(Object obj, int millisecondsTimeout, bool exitContext) { if (obj == null) - throw (new ArgumentNullException("obj")); + throw (new ArgumentNullException(nameof(obj))); return ObjWait(exitContext, millisecondsTimeout, obj); } @@ -219,16 +211,14 @@ namespace System.Threading { * Exceptions: SynchronizationLockException if this method is not called inside * a synchronized block of code. ========================================================================*/ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void ObjPulse(Object obj); - [System.Security.SecuritySafeCritical] // auto-generated public static void Pulse(Object obj) { if (obj == null) { - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); } Contract.EndContractBlock(); @@ -237,16 +227,14 @@ namespace System.Threading { /*======================================================================== ** Sends a notification to all waiting objects. ========================================================================*/ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void ObjPulseAll(Object obj); - [System.Security.SecuritySafeCritical] // auto-generated public static void PulseAll(Object obj) { if (obj == null) { - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); } Contract.EndContractBlock(); diff --git a/src/mscorlib/src/System/Threading/Mutex.cs b/src/mscorlib/src/System/Threading/Mutex.cs index 2e9b68176d..506abb7a07 100644 --- a/src/mscorlib/src/System/Threading/Mutex.cs +++ b/src/mscorlib/src/System/Threading/Mutex.cs @@ -24,31 +24,24 @@ namespace System.Threading using System.Runtime.ConstrainedExecution; using System.Runtime.Versioning; using System.Security; + using System.Diagnostics; using System.Diagnostics.Contracts; - -#if FEATURE_MACL - using System.Security.AccessControl; -#endif - [HostProtection(Synchronization=true, ExternalThreading=true)] [ComVisible(true)] public sealed class Mutex : WaitHandle { static bool dummyBool; -#if !FEATURE_MACL - public class MutexSecurity { + public class MutexSecurity + { } -#endif - [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public Mutex(bool initiallyOwned, String name, out bool createdNew) : this(initiallyOwned, name, out createdNew, (MutexSecurity)null) { } - [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public unsafe Mutex(bool initiallyOwned, String name, out bool createdNew, MutexSecurity mutexSecurity) { @@ -60,29 +53,15 @@ namespace System.Threading #if !PLATFORM_UNIX if (name != null && System.IO.Path.MaxPath < name.Length) { - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name)); } #endif Contract.EndContractBlock(); Win32Native.SECURITY_ATTRIBUTES secAttrs = null; -#if FEATURE_MACL - // For ACL's, get the security descriptor from the MutexSecurity. - if (mutexSecurity != null) { - - secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); - secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); - - byte[] sd = mutexSecurity.GetSecurityDescriptorBinaryForm(); - byte* pSecDescriptor = stackalloc byte[sd.Length]; - Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length); - secAttrs.pSecurityDescriptor = pSecDescriptor; - } -#endif CreateMutexWithGuaranteedCleanup(initiallyOwned, name, out createdNew, secAttrs); } - [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal Mutex(bool initiallyOwned, String name, out bool createdNew, Win32Native.SECURITY_ATTRIBUTES secAttrs) { @@ -94,7 +73,7 @@ namespace System.Threading #if !PLATFORM_UNIX if (name != null && System.IO.Path.MaxPath < name.Length) { - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name)); } #endif Contract.EndContractBlock(); @@ -102,7 +81,6 @@ namespace System.Threading CreateMutexWithGuaranteedCleanup(initiallyOwned, name, out createdNew, secAttrs); } - [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal void CreateMutexWithGuaranteedCleanup(bool initiallyOwned, String name, out bool createdNew, Win32Native.SECURITY_ATTRIBUTES secAttrs) { @@ -123,15 +101,13 @@ namespace System.Threading MutexCleanupInfo m_cleanupInfo; internal bool m_newMutex; String m_name; - [System.Security.SecurityCritical] // auto-generated Win32Native.SECURITY_ATTRIBUTES m_secAttrs; Mutex m_mutex; - [System.Security.SecurityCritical] // auto-generated [PrePrepareMethod] internal MutexTryCodeHelper(bool initiallyOwned,MutexCleanupInfo cleanupInfo, String name, Win32Native.SECURITY_ATTRIBUTES secAttrs, Mutex mutex) { - Contract.Assert(name == null || name.Length != 0); + Debug.Assert(name == null || name.Length != 0); m_initiallyOwned = initiallyOwned; m_cleanupInfo = cleanupInfo; @@ -140,7 +116,6 @@ namespace System.Threading m_mutex = mutex; } - [System.Security.SecurityCritical] // auto-generated [PrePrepareMethod] internal void MutexTryCode(object userData) { @@ -155,14 +130,10 @@ namespace System.Threading if (m_initiallyOwned) { m_cleanupInfo.inCriticalRegion = true; -#if !FEATURE_CORECLR - Thread.BeginThreadAffinity(); - Thread.BeginCriticalRegion(); -#endif //!FEATURE_CORECLR } } - int errorCode = 0; + int errorCode = 0; RuntimeHelpers.PrepareConstrainedRegions(); try { @@ -182,7 +153,7 @@ namespace System.Threading #if PLATFORM_UNIX case Win32Native.ERROR_FILENAME_EXCED_RANGE: // On Unix, length validation is done by CoreCLR's PAL after converting to utf-8 - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPathComponentLength), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", PathInternal.MaxComponentLength), "name"); #endif case Win32Native.ERROR_INVALID_HANDLE: @@ -199,38 +170,27 @@ namespace System.Threading } } - [System.Security.SecurityCritical] // auto-generated [PrePrepareMethod] private void MutexCleanupCode(Object userData, bool exceptionThrown) { MutexCleanupInfo cleanupInfo = (MutexCleanupInfo) userData; // If hasThreadAffinity isn't true, we've thrown an exception in the above try, and we must free the mutex - // on this OS thread before ending our thread affninity. + // on this OS thread before ending our thread affninity. if(!hasThreadAffinity) { if (cleanupInfo.mutexHandle != null && !cleanupInfo.mutexHandle.IsInvalid) { if( cleanupInfo.inCriticalRegion) { - Win32Native.ReleaseMutex(cleanupInfo.mutexHandle); + Win32Native.ReleaseMutex(cleanupInfo.mutexHandle); } - cleanupInfo.mutexHandle.Dispose(); - + cleanupInfo.mutexHandle.Dispose(); } - - if( cleanupInfo.inCriticalRegion) { -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); - Thread.EndThreadAffinity(); -#endif - } } } internal class MutexCleanupInfo { - [System.Security.SecurityCritical] // auto-generated internal SafeWaitHandle mutexHandle; internal bool inCriticalRegion; - [System.Security.SecurityCritical] // auto-generated internal MutexCleanupInfo(SafeWaitHandle mutexHandle, bool inCriticalRegion) { this.mutexHandle = mutexHandle; @@ -238,24 +198,20 @@ namespace System.Threading } } - [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public Mutex(bool initiallyOwned, String name) : this(initiallyOwned, name, out dummyBool) { } - [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public Mutex(bool initiallyOwned) : this(initiallyOwned, null, out dummyBool) { } - [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public Mutex() : this(false, null, out dummyBool) { } - [System.Security.SecurityCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private Mutex(SafeWaitHandle handle) { @@ -263,23 +219,15 @@ namespace System.Threading hasThreadAffinity = true; } - [System.Security.SecurityCritical] // auto-generated_required public static Mutex OpenExisting(string name) { -#if !FEATURE_MACL return OpenExisting(name, (MutexRights) 0); -#else // FEATURE_MACL - return OpenExisting(name, MutexRights.Modify | MutexRights.Synchronize); -#endif // FEATURE_MACL } -#if !FEATURE_MACL public enum MutexRights { } -#endif - [System.Security.SecurityCritical] // auto-generated_required public static Mutex OpenExisting(string name, MutexRights rights) { Mutex result; @@ -300,38 +248,31 @@ namespace System.Threading } } - [System.Security.SecurityCritical] // auto-generated_required public static bool TryOpenExisting(string name, out Mutex result) { -#if !FEATURE_MACL return OpenExistingWorker(name, (MutexRights)0, out result) == OpenExistingResult.Success; -#else // FEATURE_MACL - return OpenExistingWorker(name, MutexRights.Modify | MutexRights.Synchronize, out result) == OpenExistingResult.Success; -#endif // FEATURE_MACL } - [System.Security.SecurityCritical] // auto-generated_required public static bool TryOpenExisting(string name, MutexRights rights, out Mutex result) { return OpenExistingWorker(name, rights, out result) == OpenExistingResult.Success; } - [System.Security.SecurityCritical] private static OpenExistingResult OpenExistingWorker(string name, MutexRights rights, out Mutex result) { if (name == null) { - throw new ArgumentNullException("name", Environment.GetResourceString("ArgumentNull_WithParamName")); + throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_WithParamName")); } if(name.Length == 0) { - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name)); } #if !PLATFORM_UNIX if(System.IO.Path.MaxPath < name.Length) { - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name)); } #endif Contract.EndContractBlock(); @@ -342,11 +283,7 @@ namespace System.Threading // with parameters to allow us to view & edit the ACL. This will // fail if we don't have permission to view or edit the ACL's. // If that happens, ask for less permissions. -#if FEATURE_MACL - SafeWaitHandle myHandle = Win32Native.OpenMutex((int) rights, false, name); -#else SafeWaitHandle myHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name); -#endif int errorCode = 0; if (myHandle.IsInvalid) @@ -357,7 +294,7 @@ namespace System.Threading if (name != null && errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE) { // On Unix, length validation is done by CoreCLR's PAL after converting to utf-8 - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPathComponentLength), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", PathInternal.MaxComponentLength), nameof(name)); } #endif @@ -379,110 +316,51 @@ namespace System.Threading // Note: To call ReleaseMutex, you must have an ACL granting you // MUTEX_MODIFY_STATE rights (0x0001). The other interesting value // in a Mutex's ACL is MUTEX_ALL_ACCESS (0x1F0001). - [System.Security.SecuritySafeCritical] // auto-generated - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public void ReleaseMutex() { if (Win32Native.ReleaseMutex(safeWaitHandle)) { -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); - Thread.EndThreadAffinity(); -#endif } else { -#if FEATURE_CORECLR throw new Exception(Environment.GetResourceString("Arg_SynchronizationLockException")); -#else - throw new ApplicationException(Environment.GetResourceString("Arg_SynchronizationLockException")); -#endif // FEATURE_CORECLR - } + } } - [System.Security.SecurityCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - static int CreateMutexHandle(bool initiallyOwned, String name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle) { - int errorCode; - bool fAffinity = false; - - while(true) { + static int CreateMutexHandle(bool initiallyOwned, String name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle) + { + int errorCode; + + while (true) + { mutexHandle = Win32Native.CreateMutex(securityAttribute, initiallyOwned, name); - errorCode = Marshal.GetLastWin32Error(); - if( !mutexHandle.IsInvalid) { - break; - } + errorCode = Marshal.GetLastWin32Error(); + if (!mutexHandle.IsInvalid) break; - if( errorCode == Win32Native.ERROR_ACCESS_DENIED) { - // If a mutex with the name already exists, OS will try to open it with FullAccess. - // It might fail if we don't have enough access. In that case, we try to open the mutex will modify and synchronize access. - // - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - try - { - } - finally - { -#if !FEATURE_CORECLR - Thread.BeginThreadAffinity(); -#endif - fAffinity = true; - } - mutexHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name); - if(!mutexHandle.IsInvalid) - { - errorCode = Win32Native.ERROR_ALREADY_EXISTS; - } - else - { - errorCode = Marshal.GetLastWin32Error(); - } - } - finally - { - if (fAffinity) { -#if !FEATURE_CORECLR - Thread.EndThreadAffinity(); -#endif - } - } + if (errorCode != Win32Native.ERROR_ACCESS_DENIED) break; - // There could be a race condition here, the other owner of the mutex can free the mutex, - // We need to retry creation in that case. - if( errorCode != Win32Native.ERROR_FILE_NOT_FOUND) { - if( errorCode == Win32Native.ERROR_SUCCESS) { - errorCode = Win32Native.ERROR_ALREADY_EXISTS; - } - break; - } - } - else { + // If a mutex with the name already exists, OS will try to open it with FullAccess. + // It might fail if we don't have enough access. In that case, we try to open the mutex will modify and synchronize access. + RuntimeHelpers.PrepareConstrainedRegions(); + + mutexHandle = Win32Native.OpenMutex( + Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, + false, + name); + + errorCode = !mutexHandle.IsInvalid ? Win32Native.ERROR_ALREADY_EXISTS : Marshal.GetLastWin32Error(); + + // There could be a race condition here, the other owner of the mutex can free the mutex, + // We need to retry creation in that case. + if (errorCode != Win32Native.ERROR_FILE_NOT_FOUND) + { + if (errorCode == Win32Native.ERROR_SUCCESS) errorCode = Win32Native.ERROR_ALREADY_EXISTS; break; } - } + } return errorCode; } - -#if FEATURE_MACL - [System.Security.SecuritySafeCritical] // auto-generated - public MutexSecurity GetAccessControl() - { - return new MutexSecurity(safeWaitHandle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group); - } - - [System.Security.SecuritySafeCritical] // auto-generated - public void SetAccessControl(MutexSecurity mutexSecurity) - { - if (mutexSecurity == null) - throw new ArgumentNullException("mutexSecurity"); - Contract.EndContractBlock(); - - mutexSecurity.Persist(safeWaitHandle); - } -#endif - } } diff --git a/src/mscorlib/src/System/Threading/Overlapped.cs b/src/mscorlib/src/System/Threading/Overlapped.cs index 3f9fbc4989..2b192c7b3a 100644 --- a/src/mscorlib/src/System/Threading/Overlapped.cs +++ b/src/mscorlib/src/System/Threading/Overlapped.cs @@ -33,6 +33,7 @@ namespace System.Threading using System.Security; using System.Security.Permissions; using System.Runtime.ConstrainedExecution; + using System.Diagnostics; using System.Diagnostics.Contracts; using System.Collections.Concurrent; @@ -60,20 +61,16 @@ namespace System.Threading unsafe internal class _IOCompletionCallback { - [System.Security.SecurityCritical] // auto-generated IOCompletionCallback _ioCompletionCallback; ExecutionContext _executionContext; uint _errorCode; // Error code uint _numBytes; // No. of bytes transferred - [SecurityCritical] NativeOverlapped* _pOVERLAP; - [System.Security.SecuritySafeCritical] // auto-generated static _IOCompletionCallback() { } - [System.Security.SecurityCritical] // auto-generated internal _IOCompletionCallback(IOCompletionCallback ioCompletionCallback, ref StackCrawlMark stackMark) { _ioCompletionCallback = ioCompletionCallback; @@ -83,21 +80,16 @@ namespace System.Threading ExecutionContext.CaptureOptions.IgnoreSyncCtx | ExecutionContext.CaptureOptions.OptimizeDefaultCase); } // Context callback: same sig for SendOrPostCallback and ContextCallback - #if FEATURE_CORECLR - [System.Security.SecurityCritical] // auto-generated - #endif static internal ContextCallback _ccb = new ContextCallback(IOCompletionCallback_Context); - [System.Security.SecurityCritical] static internal void IOCompletionCallback_Context(Object state) { _IOCompletionCallback helper = (_IOCompletionCallback)state; - Contract.Assert(helper != null,"_IOCompletionCallback cannot be null"); + Debug.Assert(helper != null,"_IOCompletionCallback cannot be null"); helper._ioCompletionCallback(helper._errorCode, helper._numBytes, helper._pOVERLAP); } // call back helper - [System.Security.SecurityCritical] // auto-generated static unsafe internal void PerformIOCompletionCallback(uint errorCode, // Error code uint numBytes, // No. of bytes transferred NativeOverlapped* pOVERLAP // ptr to OVERLAP structure @@ -146,7 +138,6 @@ namespace System.Threading // ! If you make any change to the layout here, you need to make matching change // ! to OverlappedObject in vm\nativeoverlapped.h internal IAsyncResult m_asyncResult; - [System.Security.SecurityCritical] // auto-generated internal IOCompletionCallback m_iocb; internal _IOCompletionCallback m_iocbHelper; internal Overlapped m_overlapped; @@ -162,14 +153,9 @@ namespace System.Threading #pragma warning restore 169 internal NativeOverlapped m_nativeOverlapped; -#if FEATURE_CORECLR // Adding an empty default ctor for annotation purposes - [System.Security.SecuritySafeCritical] // auto-generated internal OverlappedData(){} -#endif // FEATURE_CORECLR - - [System.Security.SecurityCritical] internal void ReInitialize() { m_asyncResult = null; @@ -177,10 +163,10 @@ namespace System.Threading m_iocbHelper = null; m_overlapped = null; m_userObject = null; - Contract.Assert(m_pinSelf.IsNull(), "OverlappedData has not been freed: m_pinSelf"); + Debug.Assert(m_pinSelf.IsNull(), "OverlappedData has not been freed: m_pinSelf"); m_pinSelf = (IntPtr)0; m_userObjectInternal = (IntPtr)0; - Contract.Assert(m_AppDomainId == 0 || m_AppDomainId == AppDomain.CurrentDomain.Id, "OverlappedData is not in the current domain"); + Debug.Assert(m_AppDomainId == 0 || m_AppDomainId == AppDomain.CurrentDomain.Id, "OverlappedData is not in the current domain"); m_AppDomainId = 0; m_nativeOverlapped.EventHandle = (IntPtr)0; m_isArray = 0; @@ -188,7 +174,6 @@ namespace System.Threading m_nativeOverlapped.InternalHigh = (IntPtr)0; } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable unsafe internal NativeOverlapped* Pack(IOCompletionCallback iocb, Object userData) { @@ -222,7 +207,6 @@ namespace System.Threading return AllocateNativeOverlapped(); } - [System.Security.SecurityCritical] // auto-generated_required unsafe internal NativeOverlapped* UnsafePack(IOCompletionCallback iocb, Object userData) { if (!m_pinSelf.IsNull()) { @@ -252,19 +236,15 @@ namespace System.Threading set { m_nativeOverlapped.EventHandle = value; } } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] unsafe private extern NativeOverlapped* AllocateNativeOverlapped(); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] unsafe internal static extern void FreeNativeOverlapped(NativeOverlapped* nativeOverlappedPtr); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] unsafe internal static extern OverlappedData GetOverlappedFromNative(NativeOverlapped* nativeOverlappedPtr); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] unsafe internal static extern void CheckVMForIOPacket(out NativeOverlapped* pOVERLAP, out uint errorCode, out uint numBytes); } @@ -281,9 +261,6 @@ namespace System.Threading private OverlappedData m_overlappedData; private static PinnableBufferCache s_overlappedDataCache = new PinnableBufferCache("System.Threading.OverlappedData", ()=> new OverlappedData()); -#if FEATURE_CORECLR - [System.Security.SecuritySafeCritical] // auto-generated -#endif public Overlapped() { m_overlappedData = (OverlappedData) s_overlappedDataCache.Allocate(); @@ -344,7 +321,6 @@ namespace System.Threading internal IOCompletionCallback UserCallback { - [System.Security.SecurityCritical] get { return m_overlappedData.m_iocb; } } @@ -353,7 +329,6 @@ namespace System.Threading * Roots the iocb and stores it in the ReservedCOR field of native Overlapped * Pins the native Overlapped struct and returns the pinned index. ====================================================================*/ - [System.Security.SecurityCritical] // auto-generated [Obsolete("This method is not safe. Use Pack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")] [CLSCompliant(false)] unsafe public NativeOverlapped* Pack(IOCompletionCallback iocb) @@ -361,14 +336,12 @@ namespace System.Threading return Pack (iocb, null); } - [System.Security.SecurityCritical] // auto-generated [CLSCompliant(false),ComVisible(false)] unsafe public NativeOverlapped* Pack(IOCompletionCallback iocb, Object userData) { return m_overlappedData.Pack(iocb, userData); } - [System.Security.SecurityCritical] // auto-generated_required [Obsolete("This method is not safe. Use UnsafePack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")] [CLSCompliant(false)] unsafe public NativeOverlapped* UnsafePack(IOCompletionCallback iocb) @@ -376,7 +349,6 @@ namespace System.Threading return UnsafePack (iocb, null); } - [System.Security.SecurityCritical] // auto-generated_required [CLSCompliant(false), ComVisible(false)] unsafe public NativeOverlapped* UnsafePack(IOCompletionCallback iocb, Object userData) { @@ -387,12 +359,11 @@ namespace System.Threading * Unpacks an unmanaged native Overlapped struct. * Unpins the native Overlapped struct ====================================================================*/ - [System.Security.SecurityCritical] // auto-generated [CLSCompliant(false)] unsafe public static Overlapped Unpack(NativeOverlapped* nativeOverlappedPtr) { if (nativeOverlappedPtr == null) - throw new ArgumentNullException("nativeOverlappedPtr"); + throw new ArgumentNullException(nameof(nativeOverlappedPtr)); Contract.EndContractBlock(); Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped; @@ -400,12 +371,11 @@ namespace System.Threading return overlapped; } - [System.Security.SecurityCritical] // auto-generated [CLSCompliant(false)] unsafe public static void Free(NativeOverlapped* nativeOverlappedPtr) { if (nativeOverlappedPtr == null) - throw new ArgumentNullException("nativeOverlappedPtr"); + throw new ArgumentNullException(nameof(nativeOverlappedPtr)); Contract.EndContractBlock(); Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped; diff --git a/src/mscorlib/src/System/Threading/ReaderWriterLock.cs b/src/mscorlib/src/System/Threading/ReaderWriterLock.cs index 8cead1a87a..e35ac7685b 100644 --- a/src/mscorlib/src/System/Threading/ReaderWriterLock.cs +++ b/src/mscorlib/src/System/Threading/ReaderWriterLock.cs @@ -25,14 +25,12 @@ namespace System.Threading { using System.Runtime.Versioning; using System.Diagnostics.Contracts; - [HostProtection(Synchronization=true, ExternalThreading=true)] [ComVisible(true)] public sealed class ReaderWriterLock: CriticalFinalizerObject { /* * Constructor */ - [System.Security.SecuritySafeCritical] // auto-generated public ReaderWriterLock() { PrivateInitialize(); @@ -41,7 +39,6 @@ namespace System.Threading { /* * Destructor */ - [System.Security.SecuritySafeCritical] // auto-generated ~ReaderWriterLock() { PrivateDestruct(); @@ -52,7 +49,6 @@ namespace System.Threading { * by the current thread */ public bool IsReaderLockHeld { - [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return(PrivateGetIsReaderLockHeld()); @@ -64,7 +60,6 @@ namespace System.Threading { * by the current thread */ public bool IsWriterLockHeld { - [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return(PrivateGetIsWriterLockHeld()); @@ -77,7 +72,6 @@ namespace System.Threading { * meaningful results */ public int WriterSeqNum { - [System.Security.SecuritySafeCritical] // auto-generated get { return(PrivateGetWriterSeqNum()); } @@ -87,23 +81,20 @@ namespace System.Threading { * Acquires reader lock. The thread will block if a different * thread has writer lock. */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void AcquireReaderLockInternal(int millisecondsTimeout); - [System.Security.SecuritySafeCritical] // auto-generated public void AcquireReaderLock(int millisecondsTimeout) { AcquireReaderLockInternal(millisecondsTimeout); } - [System.Security.SecuritySafeCritical] // auto-generated public void AcquireReaderLock(TimeSpan timeout) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); AcquireReaderLockInternal((int)tm); } @@ -113,22 +104,19 @@ namespace System.Threading { * has reader lock. Use UpgardeToWriterLock when you are not * sure if the thread has reader lock */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void AcquireWriterLockInternal(int millisecondsTimeout); - [System.Security.SecuritySafeCritical] // auto-generated public void AcquireWriterLock(int millisecondsTimeout) { AcquireWriterLockInternal(millisecondsTimeout); } - [System.Security.SecuritySafeCritical] // auto-generated public void AcquireWriterLock(TimeSpan timeout) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); AcquireWriterLockInternal((int)tm); } @@ -136,12 +124,10 @@ namespace System.Threading { /* * Releases reader lock. */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private extern void ReleaseReaderLockInternal(); - [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public void ReleaseReaderLock() { @@ -151,12 +137,10 @@ namespace System.Threading { /* * Releases writer lock. */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private extern void ReleaseWriterLockInternal(); - [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public void ReleaseWriterLock() { @@ -168,7 +152,6 @@ namespace System.Threading { * reader, it is possible that the reader lock was * released before writer lock was acquired. */ - [System.Security.SecuritySafeCritical] // auto-generated public LockCookie UpgradeToWriterLock(int millisecondsTimeout) { LockCookie result = new LockCookie (); @@ -176,7 +159,6 @@ namespace System.Threading { return result; } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void FCallUpgradeToWriterLock(ref LockCookie result, int millisecondsTimeout); @@ -184,7 +166,7 @@ namespace System.Threading { { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); return UpgradeToWriterLock((int)tm); } @@ -192,11 +174,9 @@ namespace System.Threading { * Restores the lock status of the thread to the one it was * in when it called UpgradeToWriterLock. */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void DowngradeFromWriterLockInternal(ref LockCookie lockCookie); - [System.Security.SecuritySafeCritical] // auto-generated public void DowngradeFromWriterLock(ref LockCookie lockCookie) { DowngradeFromWriterLockInternal(ref lockCookie); @@ -206,7 +186,6 @@ namespace System.Threading { * Releases the lock irrespective of the number of times the thread * acquired the lock */ - [System.Security.SecuritySafeCritical] // auto-generated public LockCookie ReleaseLock() { LockCookie result = new LockCookie (); @@ -214,7 +193,6 @@ namespace System.Threading { return result; } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void FCallReleaseLock(ref LockCookie result); @@ -222,11 +200,9 @@ namespace System.Threading { * Restores the lock status of the thread to the one it was * in when it called ReleaseLock. */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void RestoreLockInternal(ref LockCookie lockCookie); - [System.Security.SecuritySafeCritical] // auto-generated public void RestoreLock(ref LockCookie lockCookie) { RestoreLockInternal(ref lockCookie); @@ -236,7 +212,6 @@ namespace System.Threading { * Internal helper that returns TRUE if the reader lock is held * by the current thread */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private extern bool PrivateGetIsReaderLockHeld(); @@ -245,7 +220,6 @@ namespace System.Threading { * Internal helper that returns TRUE if the writer lock is held * by the current thread */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private extern bool PrivateGetIsWriterLockHeld(); @@ -255,7 +229,6 @@ namespace System.Threading { * number. The caller should be a reader or writer for getting * meaningful results */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int PrivateGetWriterSeqNum(); @@ -264,17 +237,14 @@ namespace System.Threading { * sequence number was obtained. The caller should be * a reader or writer for getting meaningful results */ - [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern bool AnyWritersSince(int seqNum); // Initialize state kept inside the lock - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void PrivateInitialize(); // Destruct resource associated with the lock - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void PrivateDestruct(); diff --git a/src/mscorlib/src/System/Threading/Semaphore.cs b/src/mscorlib/src/System/Threading/Semaphore.cs index 303593b776..1eac4aaaeb 100644 --- a/src/mscorlib/src/System/Threading/Semaphore.cs +++ b/src/mscorlib/src/System/Threading/Semaphore.cs @@ -4,6 +4,7 @@ using Microsoft.Win32; using Microsoft.Win32.SafeHandles; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.IO; using System.Runtime.InteropServices; @@ -13,20 +14,18 @@ namespace System.Threading { public sealed partial class Semaphore : WaitHandle { - [SecuritySafeCritical] public Semaphore(int initialCount, int maximumCount) : this(initialCount, maximumCount, null) { } - [SecurityCritical] public Semaphore(int initialCount, int maximumCount, string name) { if (initialCount < 0) { - throw new ArgumentOutOfRangeException("initialCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(initialCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); } if (maximumCount < 1) { - throw new ArgumentOutOfRangeException("maximumCount", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); + throw new ArgumentOutOfRangeException(nameof(maximumCount), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); } if (initialCount > maximumCount) @@ -49,17 +48,16 @@ namespace System.Threading this.SafeWaitHandle = myHandle; } - [SecurityCritical] public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew) { if (initialCount < 0) { - throw new ArgumentOutOfRangeException("initialCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(initialCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); } if (maximumCount < 1) { - throw new ArgumentOutOfRangeException("maximumCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(maximumCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); } if (initialCount > maximumCount) @@ -81,13 +79,11 @@ namespace System.Threading this.SafeWaitHandle = myHandle; } - [SecurityCritical] private Semaphore(SafeWaitHandle handle) { this.SafeWaitHandle = handle; } - [SecurityCritical] private static SafeWaitHandle CreateSemaphone(int initialCount, int maximumCount, string name) { if (name != null) @@ -96,19 +92,17 @@ namespace System.Threading throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives")); #else if (name.Length > Path.MaxPath) - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name)); #endif } - Contract.Assert(initialCount >= 0); - Contract.Assert(maximumCount >= 1); - Contract.Assert(initialCount <= maximumCount); + Debug.Assert(initialCount >= 0); + Debug.Assert(maximumCount >= 1); + Debug.Assert(initialCount <= maximumCount); return Win32Native.CreateSemaphore(null, initialCount, maximumCount, name); } - [SecurityCritical] - public static Semaphore OpenExisting(string name) { Semaphore result; @@ -125,24 +119,22 @@ namespace System.Threading } } - [SecurityCritical] public static bool TryOpenExisting(string name, out Semaphore result) { return OpenExistingWorker(name, out result) == OpenExistingResult.Success; } - [SecurityCritical] private static OpenExistingResult OpenExistingWorker(string name, out Semaphore result) { #if PLATFORM_UNIX throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives")); #else if (name == null) - throw new ArgumentNullException("name", Environment.GetResourceString("ArgumentNull_WithParamName")); + throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_WithParamName")); if (name.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name)); if (name.Length > Path.MaxPath) - throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name"); + throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name)); const int SYNCHRONIZE = 0x00100000; const int SEMAPHORE_MODIFY_STATE = 0x00000002; @@ -177,12 +169,11 @@ namespace System.Threading } // increase the count on a semaphore, returns previous count - [SecuritySafeCritical] public int Release(int releaseCount) { if (releaseCount < 1) { - throw new ArgumentOutOfRangeException("releaseCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(releaseCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); } //If ReleaseSempahore returns false when the specified value would cause diff --git a/src/mscorlib/src/System/Threading/SemaphoreFullException.cs b/src/mscorlib/src/System/Threading/SemaphoreFullException.cs index e1928e05de..01c5040b7e 100644 --- a/src/mscorlib/src/System/Threading/SemaphoreFullException.cs +++ b/src/mscorlib/src/System/Threading/SemaphoreFullException.cs @@ -9,9 +9,6 @@ namespace System.Threading { [Serializable] [ComVisibleAttribute(false)] -#if !FEATURE_CORECLR - [System.Runtime.CompilerServices.TypeForwardedFrom("System, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")] -#endif public class SemaphoreFullException : SystemException { public SemaphoreFullException() : base(Environment.GetResourceString("Threading_SemaphoreFullException")){ diff --git a/src/mscorlib/src/System/Threading/SemaphoreSlim.cs b/src/mscorlib/src/System/Threading/SemaphoreSlim.cs index c2dcbb3451..92d760d77d 100644 --- a/src/mscorlib/src/System/Threading/SemaphoreSlim.cs +++ b/src/mscorlib/src/System/Threading/SemaphoreSlim.cs @@ -40,7 +40,6 @@ namespace System.Threading /// </para> /// </remarks> [ComVisible(false)] - [HostProtection(Synchronization = true, ExternalThreading = true)] [DebuggerDisplay("Current Count = {m_currentCount}")] public class SemaphoreSlim : IDisposable { @@ -89,14 +88,12 @@ namespace System.Threading internal TaskNode Prev, Next; internal TaskNode() : base() {} - [SecurityCritical] void IThreadPoolWorkItem.ExecuteWorkItem() { bool setSuccessfully = TrySetResult(true); - Contract.Assert(setSuccessfully, "Should have been able to complete task"); + Debug.Assert(setSuccessfully, "Should have been able to complete task"); } - [SecurityCritical] void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { /* nop */ } } #endregion @@ -182,13 +179,13 @@ namespace System.Threading if (initialCount < 0 || initialCount > maxCount) { throw new ArgumentOutOfRangeException( - "initialCount", initialCount, GetResourceString("SemaphoreSlim_ctor_InitialCountWrong")); + nameof(initialCount), initialCount, GetResourceString("SemaphoreSlim_ctor_InitialCountWrong")); } //validate input if (maxCount <= 0) { - throw new ArgumentOutOfRangeException("maxCount", maxCount, GetResourceString("SemaphoreSlim_ctor_MaxCountWrong")); + throw new ArgumentOutOfRangeException(nameof(maxCount), maxCount, GetResourceString("SemaphoreSlim_ctor_MaxCountWrong")); } m_maxCount = maxCount; @@ -245,7 +242,7 @@ namespace System.Threading if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue) { throw new System.ArgumentOutOfRangeException( - "timeout", timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong")); + nameof(timeout), timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong")); } // Call wait with the timeout milliseconds @@ -275,7 +272,7 @@ namespace System.Threading if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue) { throw new System.ArgumentOutOfRangeException( - "timeout", timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong")); + nameof(timeout), timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong")); } // Call wait with the timeout milliseconds @@ -372,7 +369,7 @@ namespace System.Threading // then block on (once we've released the lock). if (m_asyncHead != null) { - Contract.Assert(m_asyncTail != null, "tail should not be null if head isn't"); + Debug.Assert(m_asyncTail != null, "tail should not be null if head isn't"); asyncWaitTask = WaitAsync(millisecondsTimeout, cancellationToken); } // There are no async waiters, so we can proceed with normal synchronous waiting. @@ -404,7 +401,7 @@ namespace System.Threading // defer to synchronous waiters in priority, which means that if it's possible an asynchronous // waiter didn't get released because a synchronous waiter was present, we need to ensure // that synchronous waiter succeeds so that they have a chance to release. - Contract.Assert(!waitSuccessful || m_currentCount > 0, + Debug.Assert(!waitSuccessful || m_currentCount > 0, "If the wait was successful, there should be count available."); if (m_currentCount > 0) { @@ -579,7 +576,7 @@ namespace System.Threading if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue) { throw new System.ArgumentOutOfRangeException( - "timeout", timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong")); + nameof(timeout), timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong")); } // Call wait with the timeout milliseconds @@ -638,7 +635,7 @@ namespace System.Threading // the semaphore or when the timeout expired or cancellation was requested. else { - Contract.Assert(m_currentCount == 0, "m_currentCount should never be negative"); + Debug.Assert(m_currentCount == 0, "m_currentCount should never be negative"); var asyncWaiter = CreateAndAddAsyncWaiter(); return (millisecondsTimeout == Timeout.Infinite && !cancellationToken.CanBeCanceled) ? asyncWaiter : @@ -651,7 +648,7 @@ namespace System.Threading /// <returns>The created task.</returns> private TaskNode CreateAndAddAsyncWaiter() { - Contract.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held"); + Debug.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held"); // Create the task var task = new TaskNode(); @@ -659,13 +656,13 @@ namespace System.Threading // Add it to the linked list if (m_asyncHead == null) { - Contract.Assert(m_asyncTail == null, "If head is null, so too should be tail"); + Debug.Assert(m_asyncTail == null, "If head is null, so too should be tail"); m_asyncHead = task; m_asyncTail = task; } else { - Contract.Assert(m_asyncTail != null, "If head is not null, neither should be tail"); + Debug.Assert(m_asyncTail != null, "If head is not null, neither should be tail"); m_asyncTail.Next = task; task.Prev = m_asyncTail; m_asyncTail = task; @@ -681,7 +678,7 @@ namespace System.Threading private bool RemoveAsyncWaiter(TaskNode task) { Contract.Requires(task != null, "Expected non-null task"); - Contract.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held"); + Debug.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held"); // Is the task in the list? To be in the list, either it's the head or it has a predecessor that's in the list. bool wasInList = m_asyncHead == task || task.Prev != null; @@ -691,7 +688,7 @@ namespace System.Threading if (task.Prev != null) task.Prev.Next = task.Next; if (m_asyncHead == task) m_asyncHead = task.Next; if (m_asyncTail == task) m_asyncTail = task.Prev; - Contract.Assert((m_asyncHead == null) == (m_asyncTail == null), "Head is null iff tail is null"); + Debug.Assert((m_asyncHead == null) == (m_asyncTail == null), "Head is null iff tail is null"); // Make sure not to leak task.Next = task.Prev = null; @@ -706,8 +703,8 @@ namespace System.Threading /// <returns>The task to return to the caller.</returns> private async Task<bool> WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, int millisecondsTimeout, CancellationToken cancellationToken) { - Contract.Assert(asyncWaiter != null, "Waiter should have been constructed"); - Contract.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held"); + Debug.Assert(asyncWaiter != null, "Waiter should have been constructed"); + Debug.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held"); // Wait until either the task is completed, timeout occurs, or cancellation is requested. // We need to ensure that the Task.Delay task is appropriately cleaned up if the await @@ -776,7 +773,7 @@ namespace System.Threading if (releaseCount < 1) { throw new ArgumentOutOfRangeException( - "releaseCount", releaseCount, GetResourceString("SemaphoreSlim_Release_CountWrong")); + nameof(releaseCount), releaseCount, GetResourceString("SemaphoreSlim_Release_CountWrong")); } int returnCount; @@ -797,14 +794,12 @@ namespace System.Threading // Signal to any synchronous waiters int waitCount = m_waitCount; - if (currentCount == 1 || waitCount == 1) + + int waitersToNotify = Math.Min(releaseCount, waitCount); + for (int i = 0; i < waitersToNotify; i++) { Monitor.Pulse(m_lockObj); } - else if (waitCount > 1) - { - Monitor.PulseAll(m_lockObj); - } // Now signal to any asynchronous waiters, if there are any. While we've already // signaled the synchronous waiters, we still hold the lock, and thus @@ -814,7 +809,7 @@ namespace System.Threading // waits are canceled, but the wait code path will handle that. if (m_asyncHead != null) { - Contract.Assert(m_asyncTail != null, "tail should not be null if head isn't null"); + Debug.Assert(m_asyncTail != null, "tail should not be null if head isn't null"); int maxAsyncToRelease = currentCount - waitCount; while (maxAsyncToRelease > 0 && m_asyncHead != null) { @@ -844,7 +839,6 @@ namespace System.Threading /// Queues a waiter task to the ThreadPool. We use this small helper method so that /// the larger Release(count) method does not need to be SecuritySafeCritical. /// </summary> - [SecuritySafeCritical] // for ThreadPool.UnsafeQueueCustomWorkItem private static void QueueWaiterTask(TaskNode waiterTask) { ThreadPool.UnsafeQueueCustomWorkItem(waiterTask, forceGlobal: false); @@ -898,7 +892,7 @@ namespace System.Threading private static void CancellationTokenCanceledEventHandler(object obj) { SemaphoreSlim semaphore = obj as SemaphoreSlim; - Contract.Assert(semaphore != null, "Expected a SemaphoreSlim"); + Debug.Assert(semaphore != null, "Expected a SemaphoreSlim"); lock (semaphore.m_lockObj) { Monitor.PulseAll(semaphore.m_lockObj); //wake up all waiters. diff --git a/src/mscorlib/src/System/Threading/SpinLock.cs b/src/mscorlib/src/System/Threading/SpinLock.cs index dea87435a7..1d90890d6e 100644 --- a/src/mscorlib/src/System/Threading/SpinLock.cs +++ b/src/mscorlib/src/System/Threading/SpinLock.cs @@ -12,11 +12,11 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; -using System.Diagnostics; using System.Security.Permissions; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace System.Threading @@ -55,7 +55,6 @@ namespace System.Threading /// </para> /// </remarks> [ComVisible(false)] - [HostProtection(Synchronization = true, ExternalThreading = true)] [DebuggerTypeProxy(typeof(SystemThreading_SpinLockDebugView))] [DebuggerDisplay("IsHeld = {IsHeld}")] public struct SpinLock @@ -107,7 +106,6 @@ namespace System.Threading // The waiters count is calculated by m_owner & WAITERS_MASK 01111....110 private static int MAXIMUM_WAITERS = WAITERS_MASK; - /// <summary> /// Initializes a new instance of the <see cref="T:System.Threading.SpinLock"/> /// structure with the option to track thread IDs to improve debugging. @@ -123,11 +121,10 @@ namespace System.Threading if (!enableThreadOwnerTracking) { m_owner |= LOCK_ID_DISABLE_MASK; - Contract.Assert(!IsThreadOwnerTrackingEnabled, "property should be false by now"); + Debug.Assert(!IsThreadOwnerTrackingEnabled, "property should be false by now"); } } - /// <summary> /// Initializes a new instance of the <see cref="T:System.Threading.SpinLock"/> /// structure with the option to track thread IDs to improve debugging. @@ -157,9 +154,6 @@ namespace System.Threading /// </exception> public void Enter(ref bool lockTaken) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif //Try to keep the code and branching in this method as small as possible in order to inline the method int observedOwner = m_owner; if (lockTaken || //invalid parameter @@ -225,7 +219,7 @@ namespace System.Threading if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { throw new System.ArgumentOutOfRangeException( - "timeout", timeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); + nameof(timeout), timeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); } // Call reliable enter with the int-based timeout milliseconds @@ -256,10 +250,6 @@ namespace System.Threading /// a negative number other than -1, which represents an infinite time-out.</exception> public void TryEnter(int millisecondsTimeout, ref bool lockTaken) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif - int observedOwner = m_owner; if (millisecondsTimeout < -1 || //invalid parameter lockTaken || //invalid parameter @@ -277,10 +267,6 @@ namespace System.Threading /// <param name="lockTaken">The lockTaken param</param> private void ContinueTryEnter(int millisecondsTimeout, ref bool lockTaken) { - //Leave the critical region which is entered by the fast path -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif // The fast path doesn't throw any exception, so we have to validate the parameters here if (lockTaken) { @@ -291,23 +277,15 @@ namespace System.Threading if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException( - "millisecondsTimeout", millisecondsTimeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); + nameof(millisecondsTimeout), millisecondsTimeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); } - uint startTime = 0; if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout != 0) { startTime = TimeoutHelper.GetTime(); } -#if !FEATURE_CORECLR - if (CdsSyncEtwBCLProvider.Log.IsEnabled()) - { - CdsSyncEtwBCLProvider.Log.SpinLock_FastPathFailed(m_owner); - } -#endif - if (IsThreadOwnerTrackingEnabled) { // Slow path for enabled thread tracking mode @@ -333,18 +311,22 @@ namespace System.Threading observedOwner = m_owner; if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif - if (Interlocked.CompareExchange(ref m_owner, observedOwner | 1, observedOwner, ref lockTaken) == observedOwner) { + // Aquired lock return; } -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif + if (millisecondsTimeout == 0) + { + // Did not aquire lock in CompareExchange and timeout is 0 so fail fast + return; + } + } + else if (millisecondsTimeout == 0) + { + // Did not aquire lock as owned and timeout is 0 so fail fast + return; } else //failed to acquire the lock,then try to update the waiters. If the waiters count reached the maximum, jsut break the loop to avoid overflow { @@ -352,17 +334,6 @@ namespace System.Threading turn = (Interlocked.Add(ref m_owner, 2) & WAITERS_MASK) >> 1 ; } - - - // Check the timeout. - if (millisecondsTimeout == 0 || - (millisecondsTimeout != Timeout.Infinite && - TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0)) - { - DecrementWaiters(); - return; - } - //***Step 2. Spinning //lock acquired failed and waiters updated int processorCount = PlatformHelper.ProcessorCount; @@ -377,32 +348,24 @@ namespace System.Threading observedOwner = m_owner; if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif - int newOwner = (observedOwner & WAITERS_MASK) == 0 ? // Gets the number of waiters, if zero observedOwner | 1 // don't decrement it. just set the lock bit, it is zzero because a previous call of Exit(false) ehich corrupted the waiters : (observedOwner - 2) | 1; // otherwise decrement the waiters and set the lock bit - Contract.Assert((newOwner & WAITERS_MASK) >= 0); + Debug.Assert((newOwner & WAITERS_MASK) >= 0); if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner, ref lockTaken) == observedOwner) { return; } - -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif } } - } - // Check the timeout. - if (millisecondsTimeout != Timeout.Infinite && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0) - { - DecrementWaiters(); - return; + // Check the timeout. + if (millisecondsTimeout != Timeout.Infinite && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0) + { + DecrementWaiters(); + return; + } } //*** Step 3, Yielding @@ -413,22 +376,15 @@ namespace System.Threading observedOwner = m_owner; if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif int newOwner = (observedOwner & WAITERS_MASK) == 0 ? // Gets the number of waiters, if zero observedOwner | 1 // don't decrement it. just set the lock bit, it is zzero because a previous call of Exit(false) ehich corrupted the waiters : (observedOwner - 2) | 1; // otherwise decrement the waiters and set the lock bit - Contract.Assert((newOwner & WAITERS_MASK) >= 0); + Debug.Assert((newOwner & WAITERS_MASK) >= 0); if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner, ref lockTaken) == observedOwner) { return; } - -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif } if (yieldsoFar % SLEEP_ONE_FREQUENCY == 0) @@ -470,7 +426,7 @@ namespace System.Threading if ((observedOwner & WAITERS_MASK) == 0) return; // don't decrement the waiters if it's corrupted by previous call of Exit(false) if (Interlocked.CompareExchange(ref m_owner, observedOwner - 2, observedOwner) == observedOwner) { - Contract.Assert(!IsThreadOwnerTrackingEnabled); // Make sure the waiters never be negative which will cause the thread tracking bit to be flipped + Debug.Assert(!IsThreadOwnerTrackingEnabled); // Make sure the waiters never be negative which will cause the thread tracking bit to be flipped break; } spinner.SpinOnce(); @@ -483,7 +439,7 @@ namespace System.Threading /// </summary> private void ContinueTryEnterWithThreadTracking(int millisecondsTimeout, uint startTime, ref bool lockTaken) { - Contract.Assert(IsThreadOwnerTrackingEnabled); + Debug.Assert(IsThreadOwnerTrackingEnabled); int lockUnowned = 0; // We are using thread IDs to mark ownership. Snap the thread ID and check for recursion. @@ -510,17 +466,10 @@ namespace System.Threading if (m_owner == lockUnowned) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif if (Interlocked.CompareExchange(ref m_owner, m_newOwner, lockUnowned, ref lockTaken) == lockUnowned) { return; } -#if !FEATURE_CORECLR - // The thread failed to get the lock, so we don't need to remain in a critical region. - Thread.EndCriticalRegion(); -#endif } // Check the timeout. We only RDTSC if the next spin will yield, to amortize the cost. if (millisecondsTimeout == 0 || @@ -550,11 +499,6 @@ namespace System.Threading ExitSlowPath(true); else Interlocked.Decrement(ref m_owner); - -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif - } /// <summary> @@ -586,10 +530,6 @@ namespace System.Threading } else ExitSlowPath(useMemoryBarrier); - -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif } /// <summary> diff --git a/src/mscorlib/src/System/Threading/SpinWait.cs b/src/mscorlib/src/System/Threading/SpinWait.cs index c2cd0b6203..1b31407e0f 100644 --- a/src/mscorlib/src/System/Threading/SpinWait.cs +++ b/src/mscorlib/src/System/Threading/SpinWait.cs @@ -14,6 +14,7 @@ using System; using System.Runtime.ConstrainedExecution; using System.Security.Permissions; using System.Threading; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Diagnostics.CodeAnalysis; @@ -69,7 +70,6 @@ namespace System.Threading /// threads must spin, each should use its own instance of SpinWait. /// </para> /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public struct SpinWait { @@ -132,10 +132,6 @@ namespace System.Threading // remove the thread from the scheduler's queue for 10+ms, if the system is // configured to use the (default) coarse-grained system timer. // - -#if !FEATURE_CORECLR - CdsSyncEtwBCLProvider.Log.SpinWait_NextSpinWillYield(); -#endif int yieldsSoFar = (m_count >= YIELD_THRESHOLD ? m_count - YIELD_THRESHOLD : m_count); if ((yieldsSoFar % SLEEP_1_EVERY_HOW_MANY_TIMES) == (SLEEP_1_EVERY_HOW_MANY_TIMES - 1)) @@ -197,7 +193,7 @@ namespace System.Threading #endif SpinUntil(condition, Timeout.Infinite); #if DEBUG - Contract.Assert(result); + Debug.Assert(result); #endif } @@ -220,7 +216,7 @@ namespace System.Threading if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue) { throw new System.ArgumentOutOfRangeException( - "timeout", timeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong")); + nameof(timeout), timeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong")); } // Call wait with the timeout milliseconds @@ -242,11 +238,11 @@ namespace System.Threading if (millisecondsTimeout < Timeout.Infinite) { throw new ArgumentOutOfRangeException( - "millisecondsTimeout", millisecondsTimeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong")); + nameof(millisecondsTimeout), millisecondsTimeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong")); } if (condition == null) { - throw new ArgumentNullException("condition", Environment.GetResourceString("SpinWait_SpinUntil_ArgumentNull")); + throw new ArgumentNullException(nameof(condition), Environment.GetResourceString("SpinWait_SpinUntil_ArgumentNull")); } uint startTime = 0; if (millisecondsTimeout != 0 && millisecondsTimeout != Timeout.Infinite) @@ -304,7 +300,7 @@ namespace System.Threading s_lastProcessorCountRefreshTicks = now; } - Contract.Assert(procCount > 0 && procCount <= 64, + Debug.Assert(procCount > 0 && procCount <= 64, "Processor count not within the expected range (1 - 64)."); return procCount; @@ -345,7 +341,7 @@ namespace System.Threading public static int UpdateTimeOut(uint startTime, int originalWaitMillisecondsTimeout) { // The function must be called in case the time out is not infinite - Contract.Assert(originalWaitMillisecondsTimeout != Timeout.Infinite); + Debug.Assert(originalWaitMillisecondsTimeout != Timeout.Infinite); uint elapsedMilliseconds = (GetTime() - startTime); diff --git a/src/mscorlib/src/System/Threading/SynchronizationContext.cs b/src/mscorlib/src/System/Threading/SynchronizationContext.cs index a3f28d1d73..5531597229 100644 --- a/src/mscorlib/src/System/Threading/SynchronizationContext.cs +++ b/src/mscorlib/src/System/Threading/SynchronizationContext.cs @@ -24,6 +24,7 @@ namespace System.Threading using System.Runtime.ConstrainedExecution; using System.Reflection; using System.Security; + using System.Diagnostics; using System.Diagnostics.Contracts; using System.Diagnostics.CodeAnalysis; @@ -43,17 +44,12 @@ namespace System.Threading // I'd like this to be an interface, or at least an abstract class - but neither seems to play nice with FriendAccessAllowed. // [FriendAccessAllowed] - [SecurityCritical] internal class WinRTSynchronizationContextFactoryBase { - [SecurityCritical] public virtual SynchronizationContext Create(object coreDispatcher) {return null;} } #endif //FEATURE_COMINTEROP -#if !FEATURE_CORECLR - [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags =SecurityPermissionFlag.ControlPolicy|SecurityPermissionFlag.ControlEvidence)] -#endif public class SynchronizationContext { #if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT @@ -76,7 +72,6 @@ namespace System.Threading static Type s_cachedPreparedType5; // protected so that only the derived sync context class can enable these flags - [System.Security.SecuritySafeCritical] // auto-generated [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "We never dereference s_cachedPreparedType*, so ordering is unimportant")] protected void SetWaitNotificationRequired() { @@ -143,39 +138,43 @@ namespace System.Threading } #if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT - // Method called when the CLR does a wait operation - [System.Security.SecurityCritical] // auto-generated_required + // Method called when the CLR does a wait operation [CLSCompliant(false)] [PrePrepareMethod] public virtual int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout) { + return WaitHelper(waitHandles, waitAll, millisecondsTimeout); + } + + // Method that can be called by Wait overrides + [CLSCompliant(false)] + [PrePrepareMethod] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + protected static int WaitHelper(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout) + { if (waitHandles == null) { - throw new ArgumentNullException("waitHandles"); + throw new ArgumentNullException(nameof(waitHandles)); } Contract.EndContractBlock(); - return WaitHelper(waitHandles, waitAll, millisecondsTimeout); + + return WaitHelperNative(waitHandles, waitAll, millisecondsTimeout); } - - // Static helper to which the above method can delegate to in order to get the default + + // Static helper to which the above method can delegate to in order to get the default // COM behavior. - [System.Security.SecurityCritical] // auto-generated_required [CLSCompliant(false)] [PrePrepareMethod] - [MethodImplAttribute(MethodImplOptions.InternalCall)] + [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected static extern int WaitHelper(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout); + private static extern int WaitHelperNative(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout); #endif -#if FEATURE_CORECLR - - [System.Security.SecurityCritical] public static void SetSynchronizationContext(SynchronizationContext syncContext) { Thread.CurrentThread.SynchronizationContext = syncContext; } - [System.Security.SecurityCritical] public static void SetThreadStaticContext(SynchronizationContext syncContext) { Thread.CurrentThread.SynchronizationContext = syncContext; @@ -206,56 +205,11 @@ namespace System.Threading } } -#else //FEATURE_CORECLR - - // set SynchronizationContext on the current thread - [System.Security.SecurityCritical] // auto-generated_required - public static void SetSynchronizationContext(SynchronizationContext syncContext) - { - ExecutionContext ec = Thread.CurrentThread.GetMutableExecutionContext(); - ec.SynchronizationContext = syncContext; - ec.SynchronizationContextNoFlow = syncContext; - } - - // Get the current SynchronizationContext on the current thread - public static SynchronizationContext Current - { - get - { - return Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext ?? GetThreadLocalContext(); - } - } - - // Get the last SynchronizationContext that was set explicitly (not flowed via ExecutionContext.Capture/Run) - internal static SynchronizationContext CurrentNoFlow - { - [FriendAccessAllowed] - get - { - return Thread.CurrentThread.GetExecutionContextReader().SynchronizationContextNoFlow ?? GetThreadLocalContext(); - } - } - - private static SynchronizationContext GetThreadLocalContext() - { - SynchronizationContext context = null; - -#if FEATURE_APPX - if (context == null && AppDomain.IsAppXModel()) - context = GetWinRTContext(); -#endif - - return context; - } - -#endif //FEATURE_CORECLR - #if FEATURE_APPX - [SecuritySafeCritical] private static SynchronizationContext GetWinRTContext() { - Contract.Assert(Environment.IsWinRTSupported); - Contract.Assert(AppDomain.IsAppXModel()); + Debug.Assert(Environment.IsWinRTSupported); + Debug.Assert(AppDomain.IsAppXModel()); // // We call into the VM to get the dispatcher. This is because: @@ -274,10 +228,8 @@ namespace System.Threading return null; } - [SecurityCritical] static WinRTSynchronizationContextFactoryBase s_winRTContextFactory; - [SecurityCritical] private static WinRTSynchronizationContextFactoryBase GetWinRTSynchronizationContextFactory() { // @@ -295,7 +247,6 @@ namespace System.Threading } [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] - [SecurityCritical] [SuppressUnmanagedCodeSecurity] [return: MarshalAs(UnmanagedType.Interface)] private static extern object GetWinRTDispatcherForCurrentThread(); @@ -310,7 +261,6 @@ namespace System.Threading } #if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT - [System.Security.SecurityCritical] // auto-generated private static int InvokeWaitMethodHelper(SynchronizationContext syncContext, IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout) { return syncContext.Wait(waitHandles, waitAll, millisecondsTimeout); diff --git a/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs b/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs index c29b11a922..ec7c5aaeea 100644 --- a/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs +++ b/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs @@ -131,7 +131,6 @@ namespace System.Threading.Tasks private static Loggers f_LoggingOn; //assumes false by default // The precise static constructor will run first time somebody attempts to access this class - [SecuritySafeCritical] static AsyncCausalityTracer() { if (!Environment.IsWinRTSupported) return; @@ -153,7 +152,7 @@ namespace System.Threading.Tasks s_TracerFactory = (WFD.IAsyncCausalityTracerStatics)factory; EventRegistrationToken token = s_TracerFactory.add_TracingStatusChanged(new EventHandler<WFD.TracingStatusChangedEventArgs>(TracingStatusChangedHandler)); - Contract.Assert(token != default(EventRegistrationToken), "EventRegistrationToken is null"); + Debug.Assert(token != default(EventRegistrationToken), "EventRegistrationToken is null"); } catch (Exception ex) { @@ -165,7 +164,6 @@ namespace System.Threading.Tasks } - [SecuritySafeCritical] private static void TracingStatusChangedHandler(Object sender, WFD.TracingStatusChangedEventArgs args) { if (args.Enabled) diff --git a/src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs b/src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs index 05e6dbf1a9..71eb787c5e 100644 --- a/src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs +++ b/src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.IO; using System.Runtime.CompilerServices; @@ -62,9 +63,9 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion { /// It expects that an BeginEndAwaitableAdapter instance was supplied to the APM Begin method as the object state.</summary> public readonly static AsyncCallback Callback = (asyncResult) => { - Contract.Assert(asyncResult != null); - Contract.Assert(asyncResult.IsCompleted); - Contract.Assert(asyncResult.AsyncState is BeginEndAwaitableAdapter); + Debug.Assert(asyncResult != null); + Debug.Assert(asyncResult.IsCompleted); + Debug.Assert(asyncResult.AsyncState is BeginEndAwaitableAdapter); // Get the adapter object supplied as the "object state" to the Begin method BeginEndAwaitableAdapter adapter = (BeginEndAwaitableAdapter) asyncResult.AsyncState; @@ -81,7 +82,7 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion { Action continuation = Interlocked.Exchange(ref adapter._continuation, CALLBACK_RAN); if (continuation != null) { - Contract.Assert(continuation != CALLBACK_RAN); + Debug.Assert(continuation != CALLBACK_RAN); continuation(); } }; @@ -108,10 +109,9 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion { /// <summary>Schedules the continuation to run when the operation completes.</summary> /// <param name="continuation">The continuation.</param> - [SecurityCritical] public void UnsafeOnCompleted(Action continuation) { - Contract.Assert(continuation != null); + Debug.Assert(continuation != null); OnCompleted(continuation); } @@ -120,7 +120,7 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion { /// <param name="continuation">The continuation.</param> public void OnCompleted(Action continuation) { - Contract.Assert(continuation != null); + Debug.Assert(continuation != null); // If the continuation field is null, then set it to be the target continuation // so that when the operation completes, it'll invoke the continuation. If it's non-null, @@ -139,7 +139,7 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion { /// <returns>The IAsyncResult for the operation.</returns> public IAsyncResult GetResult() { - Contract.Assert(_asyncResult != null && _asyncResult.IsCompleted); + Debug.Assert(_asyncResult != null && _asyncResult.IsCompleted); // Get the IAsyncResult IAsyncResult result = _asyncResult; diff --git a/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs b/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs index cb4a22bb2b..c7a96b0394 100644 --- a/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs +++ b/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs @@ -28,7 +28,6 @@ namespace System.Threading.Tasks /// Provides concurrent and exclusive task schedulers that coordinate to execute /// tasks while ensuring that concurrent tasks may run concurrently and exclusive tasks never do. /// </summary> - [HostProtection(Synchronization = true, ExternalThreading = true)] [DebuggerDisplay("Concurrent={ConcurrentTaskCountForDebugger}, Exclusive={ExclusiveTaskCountForDebugger}, Mode={ModeForDebugger}")] [DebuggerTypeProxy(typeof(ConcurrentExclusiveSchedulerPair.DebugView))] public class ConcurrentExclusiveSchedulerPair @@ -101,9 +100,9 @@ namespace System.Threading.Tasks public ConcurrentExclusiveSchedulerPair(TaskScheduler taskScheduler, int maxConcurrencyLevel, int maxItemsPerTask) { // Validate arguments - if (taskScheduler == null) throw new ArgumentNullException("taskScheduler"); - if (maxConcurrencyLevel == 0 || maxConcurrencyLevel < -1) throw new ArgumentOutOfRangeException("maxConcurrencyLevel"); - if (maxItemsPerTask == 0 || maxItemsPerTask < -1) throw new ArgumentOutOfRangeException("maxItemsPerTask"); + if (taskScheduler == null) throw new ArgumentNullException(nameof(taskScheduler)); + if (maxConcurrencyLevel == 0 || maxConcurrencyLevel < -1) throw new ArgumentOutOfRangeException(nameof(maxConcurrencyLevel)); + if (maxItemsPerTask == 0 || maxItemsPerTask < -1) throw new ArgumentOutOfRangeException(nameof(maxItemsPerTask)); Contract.EndContractBlock(); // Store configuration @@ -213,13 +212,13 @@ namespace System.Threading.Tasks ThreadPool.QueueUserWorkItem(state => { var localCs = (CompletionState)state; // don't use 'cs', as it'll force a closure - Contract.Assert(!localCs.Task.IsCompleted, "Completion should only happen once."); + Debug.Assert(!localCs.Task.IsCompleted, "Completion should only happen once."); var exceptions = localCs.m_exceptions; bool success = (exceptions != null && exceptions.Count > 0) ? localCs.TrySetException(exceptions) : localCs.TrySetResult(default(VoidTaskResult)); - Contract.Assert(success, "Expected to complete completion task."); + Debug.Assert(success, "Expected to complete completion task."); }, cs); } } @@ -336,7 +335,7 @@ namespace System.Threading.Tasks // Check to see if all tasks have completed and if completion has been requested. CleanupStateIfCompletingAndQuiesced(); } - else Contract.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "The processing count must be the sentinel if it's not >= 0."); + else Debug.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "The processing count must be the sentinel if it's not >= 0."); } /// <summary> @@ -351,7 +350,7 @@ namespace System.Threading.Tasks try { // Note that we're processing exclusive tasks on the current thread - Contract.Assert(!m_threadProcessingMapping.ContainsKey(Thread.CurrentThread.ManagedThreadId), + Debug.Assert(!m_threadProcessingMapping.ContainsKey(Thread.CurrentThread.ManagedThreadId), "This thread should not yet be involved in this pair's processing."); m_threadProcessingMapping[Thread.CurrentThread.ManagedThreadId] = ProcessingMode.ProcessingExclusiveTask; @@ -372,7 +371,7 @@ namespace System.Threading.Tasks // We're no longer processing exclusive tasks on the current thread ProcessingMode currentMode; m_threadProcessingMapping.TryRemove(Thread.CurrentThread.ManagedThreadId, out currentMode); - Contract.Assert(currentMode == ProcessingMode.ProcessingExclusiveTask, + Debug.Assert(currentMode == ProcessingMode.ProcessingExclusiveTask, "Somehow we ended up escaping exclusive mode."); lock (ValueLock) @@ -382,7 +381,7 @@ namespace System.Threading.Tasks // There might be more concurrent tasks available, for example, if concurrent tasks arrived // after we exited the loop, or if we exited the loop while concurrent tasks were still // available but we hit our maxItemsPerTask limit. - Contract.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "The processing mode should not have deviated from exclusive."); + Debug.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "The processing mode should not have deviated from exclusive."); m_processingCount = 0; ProcessAsyncIfNecessary(true); } @@ -400,7 +399,7 @@ namespace System.Threading.Tasks try { // Note that we're processing concurrent tasks on the current thread - Contract.Assert(!m_threadProcessingMapping.ContainsKey(Thread.CurrentThread.ManagedThreadId), + Debug.Assert(!m_threadProcessingMapping.ContainsKey(Thread.CurrentThread.ManagedThreadId), "This thread should not yet be involved in this pair's processing."); m_threadProcessingMapping[Thread.CurrentThread.ManagedThreadId] = ProcessingMode.ProcessingConcurrentTasks; @@ -432,7 +431,7 @@ namespace System.Threading.Tasks // We're no longer processing concurrent tasks on the current thread ProcessingMode currentMode; m_threadProcessingMapping.TryRemove(Thread.CurrentThread.ManagedThreadId, out currentMode); - Contract.Assert(currentMode == ProcessingMode.ProcessingConcurrentTasks, + Debug.Assert(currentMode == ProcessingMode.ProcessingConcurrentTasks, "Somehow we ended up escaping concurrent mode."); lock (ValueLock) @@ -442,7 +441,7 @@ namespace System.Threading.Tasks // There might be more concurrent tasks available, for example, if concurrent tasks arrived // after we exited the loop, or if we exited the loop while concurrent tasks were still // available but we hit our maxItemsPerTask limit. - Contract.Assert(m_processingCount > 0, "The procesing mode should not have deviated from concurrent."); + Debug.Assert(m_processingCount > 0, "The procesing mode should not have deviated from concurrent."); if (m_processingCount > 0) --m_processingCount; ProcessAsyncIfNecessary(true); } @@ -524,10 +523,9 @@ namespace System.Threading.Tasks /// <summary>Queues a task to the scheduler.</summary> /// <param name="task">The task to be queued.</param> - [SecurityCritical] protected internal override void QueueTask(Task task) { - Contract.Assert(task != null, "Infrastructure should have provided a non-null task."); + Debug.Assert(task != null, "Infrastructure should have provided a non-null task."); lock (m_pair.ValueLock) { // If the scheduler has already had completion requested, no new work is allowed to be scheduled @@ -541,10 +539,9 @@ namespace System.Threading.Tasks /// <summary>Executes a task on this scheduler.</summary> /// <param name="task">The task to be executed.</param> - [SecuritySafeCritical] internal void ExecuteTask(Task task) { - Contract.Assert(task != null, "Infrastructure should have provided a non-null task."); + Debug.Assert(task != null, "Infrastructure should have provided a non-null task."); base.TryExecuteTask(task); } @@ -552,10 +549,9 @@ namespace System.Threading.Tasks /// <param name="task">The task to execute.</param> /// <param name="taskWasPreviouslyQueued">Whether the task was previously queued to the scheduler.</param> /// <returns>true if the task could be executed; otherwise, false.</returns> - [SecurityCritical] protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { - Contract.Assert(task != null, "Infrastructure should have provided a non-null task."); + Debug.Assert(task != null, "Infrastructure should have provided a non-null task."); // If the scheduler has had completion requested, no new work is allowed to be scheduled. // A non-locked read on m_completionRequested (in CompletionRequested) is acceptable here because: @@ -628,7 +624,7 @@ namespace System.Threading.Tasks } catch { - Contract.Assert(t.IsFaulted, "Task should be faulted due to the scheduler faulting it and throwing the exception."); + Debug.Assert(t.IsFaulted, "Task should be faulted due to the scheduler faulting it and throwing the exception."); var ignored = t.Exception; throw; } @@ -642,7 +638,6 @@ namespace System.Threading.Tasks /// This method is separated out not because of performance reasons but so that /// the SecuritySafeCritical attribute may be employed. /// </remarks> - [SecuritySafeCritical] private static bool TryExecuteTaskShim(object state) { var tuple = (Tuple<ConcurrentExclusiveTaskScheduler, Task>)state; @@ -651,7 +646,6 @@ namespace System.Threading.Tasks /// <summary>Gets for debugging purposes the tasks scheduled to this scheduler.</summary> /// <returns>An enumerable of the tasks queued.</returns> - [SecurityCritical] protected override IEnumerable<Task> GetScheduledTasks() { return m_tasks; } /// <summary>Gets the number of tasks queued to this scheduler.</summary> @@ -748,11 +742,11 @@ namespace System.Threading.Tasks exceptionThrown = false; } catch (SynchronizationLockException) { exceptionThrown = true; } - Contract.Assert(held == !exceptionThrown, "The locking scheme was not correctly followed."); + Debug.Assert(held == !exceptionThrown, "The locking scheme was not correctly followed."); } #endif #else - Contract.Assert(Monitor.IsEntered(syncObj) == held, "The locking scheme was not correctly followed."); + Debug.Assert(Monitor.IsEntered(syncObj) == held, "The locking scheme was not correctly followed."); #endif } diff --git a/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs b/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs index b1f634c707..c98e219e86 100644 --- a/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs +++ b/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs @@ -15,6 +15,7 @@ using System.Security; using System.Security.Permissions; using System.Runtime.CompilerServices; using System.Threading; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.Versioning; @@ -38,7 +39,6 @@ namespace System.Threading.Tasks /// <see cref="System.Threading.Tasks.Task{TResult}.Factory">Task{TResult}.Factory</see> property. /// </para> /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public class TaskFactory<TResult> { // Member variables, DefaultScheduler, other properties and ctors @@ -832,32 +832,17 @@ namespace System.Threading.Tasks try { - // Do NOT change the code below. - // 4.5 relies on the fact that IAsyncResult CompletedSynchronously flag needs to be set correctly, - // sadly this has not been the case that is why the behaviour from 4.5 broke 4.0 buggy apps. Any other - // change will likely brake 4.5 behavior so if possible never touch this code again. - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) + //This is 4.5 behaviour + //if we don't require synchronization, a faster set result path is taken + var asyncResult = beginMethod(iar => { - //This is 4.5 behaviour - //if we don't require synchronization, a faster set result path is taken - var asyncResult = beginMethod(iar => - { - if (!iar.CompletedSynchronously) - FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); - }, state); - if (asyncResult.CompletedSynchronously) - { - Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); - FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); - } - } - else - { - //This is the original 4.0 behaviour - var asyncResult = beginMethod(iar => - { + if (!iar.CompletedSynchronously) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); - }, state); + }, state); + if (asyncResult.CompletedSynchronously) + { + Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); + FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); } } catch @@ -969,31 +954,16 @@ namespace System.Threading.Tasks try { - // Do NOT change the code below. - // 4.5 relies on the fact that IAsyncResult CompletedSynchronously flag needs to be set correctly, - // sadly this has not been the case that is why the behaviour from 4.5 broke 4.0 buggy apps. Any other - // change will likely brake 4.5 behavior so if possible never touch this code again. - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) + //if we don't require synchronization, a faster set result path is taken + var asyncResult = beginMethod(arg1, iar => { - //if we don't require synchronization, a faster set result path is taken - var asyncResult = beginMethod(arg1, iar => - { - if (!iar.CompletedSynchronously) - FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); - }, state); - if (asyncResult.CompletedSynchronously) - { - Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); - FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); - } - } - else - { - //quirk for previous versions - var asyncResult = beginMethod(arg1, iar => - { + if (!iar.CompletedSynchronously) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); - }, state); + }, state); + if (asyncResult.CompletedSynchronously) + { + Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); + FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); } } catch @@ -1114,31 +1084,16 @@ namespace System.Threading.Tasks try { - // Do NOT change the code below. - // 4.5 relies on the fact that IAsyncResult CompletedSynchronously flag needs to be set correctly, - // sadly this has not been the case that is why the behaviour from 4.5 broke 4.0 buggy apps. Any other - // change will likely brake 4.5 behavior so if possible never touch this code again. - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) + //if we don't require synchronization, a faster set result path is taken + var asyncResult = beginMethod(arg1, arg2, iar => { - //if we don't require synchronization, a faster set result path is taken - var asyncResult = beginMethod(arg1, arg2, iar => - { - if (!iar.CompletedSynchronously) - FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); - }, state); - if (asyncResult.CompletedSynchronously) - { - Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); - FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); - } - } - else - { - //quirk for previous versions - var asyncResult = beginMethod(arg1, arg2, iar => - { + if (!iar.CompletedSynchronously) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); - }, state); + }, state); + if (asyncResult.CompletedSynchronously) + { + Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); + FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); } } catch @@ -1266,31 +1221,16 @@ namespace System.Threading.Tasks try { - // Do NOT change the code below. - // 4.5 relies on the fact that IAsyncResult CompletedSynchronously flag needs to be set correctly, - // sadly this has not been the case that is why the behaviour from 4.5 broke 4.0 buggy apps. Any other - // change will likely brake 4.5 behavior so if possible never touch this code again. - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) + //if we don't require synchronization, a faster set result path is taken + var asyncResult = beginMethod(arg1, arg2, arg3, iar => { - //if we don't require synchronization, a faster set result path is taken - var asyncResult = beginMethod(arg1, arg2, arg3, iar => - { - if (!iar.CompletedSynchronously) - FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); - }, state); - if (asyncResult.CompletedSynchronously) - { - Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); - FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); - } - } - else - { - //quirk for previous versions - var asyncResult = beginMethod(arg1, arg2, arg3, iar => - { + if (!iar.CompletedSynchronously) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); - }, state); + }, state); + if (asyncResult.CompletedSynchronously) + { + Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); + FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); } } catch @@ -1330,9 +1270,9 @@ namespace System.Threading.Tasks where TInstance : class { // Validate arguments, but only with asserts, as this is an internal only implementation. - Contract.Assert(thisRef != null, "Expected a non-null thisRef"); - Contract.Assert(beginMethod != null, "Expected a non-null beginMethod"); - Contract.Assert(endMethod != null, "Expected a non-null endMethod"); + Debug.Assert(thisRef != null, "Expected a non-null thisRef"); + Debug.Assert(beginMethod != null, "Expected a non-null beginMethod"); + Debug.Assert(endMethod != null, "Expected a non-null endMethod"); // Create the promise and start the operation. // No try/catch is necessary here as we want exceptions to bubble out, and because @@ -1345,7 +1285,7 @@ namespace System.Threading.Tasks // If it completed synchronously, we'll handle that here. if (asyncResult.CompletedSynchronously) { - Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); + Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); promise.Complete(thisRef, endMethod, asyncResult, requiresSynchronization: false); } @@ -1425,7 +1365,7 @@ namespace System.Threading.Tasks TInstance thisRef, Func<TInstance, IAsyncResult, TResult> endMethod, IAsyncResult asyncResult, bool requiresSynchronization) { - Contract.Assert(!IsCompleted, "The task should not have been completed yet."); + Debug.Assert(!IsCompleted, "The task should not have been completed yet."); // Run the end method and complete the task bool successfullySet = false; @@ -1454,7 +1394,7 @@ namespace System.Threading.Tasks { successfullySet = TrySetException(exc); } - Contract.Assert(successfullySet, "Expected the task to not yet be completed"); + Debug.Assert(successfullySet, "Expected the task to not yet be completed"); } } @@ -1801,7 +1741,7 @@ namespace System.Threading.Tasks } else { - Contract.Assert(continuationAction != null); + Debug.Assert(continuationAction != null); return starter.ContinueWith<TResult>( // use a cached delegate @@ -1854,7 +1794,7 @@ namespace System.Threading.Tasks } else { - Contract.Assert(continuationAction != null); + Debug.Assert(continuationAction != null); return starter.ContinueWith<TResult>( //the following delegate avoids closure capture as much as possible //completedTasks.Result == tasksCopy; @@ -2200,7 +2140,7 @@ namespace System.Threading.Tasks } else { - Contract.Assert(continuationAction != null); + Debug.Assert(continuationAction != null); return starter.ContinueWith<TResult>( //the following delegate avoids closure capture as much as possible //completedTask.Result is the winning task; state == continuationAction @@ -2246,7 +2186,7 @@ namespace System.Threading.Tasks } else { - Contract.Assert(continuationAction != null); + Debug.Assert(continuationAction != null); return starter.ContinueWith<TResult>( // Use a cached delegate GenericDelegateCache<TAntecedentResult,TResult>.CWAnyActionDelegate, diff --git a/src/mscorlib/src/System/Threading/Tasks/Parallel.cs b/src/mscorlib/src/System/Threading/Tasks/Parallel.cs index 5ec2ae33c0..7808943870 100644 --- a/src/mscorlib/src/System/Threading/Tasks/Parallel.cs +++ b/src/mscorlib/src/System/Threading/Tasks/Parallel.cs @@ -98,7 +98,7 @@ namespace System.Threading.Tasks set { if ((value == 0) || (value < -1)) - throw new ArgumentOutOfRangeException("MaxDegreeOfParallelism"); + throw new ArgumentOutOfRangeException(nameof(MaxDegreeOfParallelism)); m_maxDegreeOfParallelism = value; } } @@ -142,7 +142,6 @@ namespace System.Threading.Tasks /// The <see cref="T:System.Threading.Tasks.Parallel"/> class provides library-based data parallel replacements /// for common operations such as for loops, for each loops, and execution of a set of statements. /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public static class Parallel { // static counter for generating unique Fork/Join Context IDs to be used in ETW events @@ -208,11 +207,11 @@ namespace System.Threading.Tasks { if (actions == null) { - throw new ArgumentNullException("actions"); + throw new ArgumentNullException(nameof(actions)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } // Throw an ODE if we're passed a disposed CancellationToken. @@ -423,7 +422,7 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } return ForWorker<object>( @@ -452,7 +451,7 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } return ForWorker64<object>( @@ -491,11 +490,11 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForWorker<object>( @@ -534,11 +533,11 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForWorker64<object>( @@ -590,7 +589,7 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } return ForWorker<object>( @@ -620,7 +619,7 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } return ForWorker64<object>( @@ -661,11 +660,11 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForWorker<object>( @@ -707,11 +706,11 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForWorker64<object>( @@ -765,15 +764,15 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } return ForWorker( @@ -827,15 +826,15 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } return ForWorker64( @@ -900,19 +899,19 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForWorker( @@ -977,19 +976,19 @@ namespace System.Threading.Tasks { if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } @@ -1031,9 +1030,9 @@ namespace System.Threading.Tasks Func<int, ParallelLoopState, TLocal, TLocal> bodyWithLocal, Func<TLocal> localInit, Action<TLocal> localFinally) { - Contract.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithLocal == null ? 0 : 1)) == 1, + Debug.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithLocal == null ? 0 : 1)) == 1, "expected exactly one body function to be supplied"); - Contract.Assert(bodyWithLocal != null || (localInit == null && localFinally == null), + Debug.Assert(bodyWithLocal != null || (localInit == null && localFinally == null), "thread local functions should only be supplied for loops w/ thread local bodies"); // Instantiate our result. Specifics will be filled in later. @@ -1157,12 +1156,12 @@ namespace System.Threading.Tasks if (bodyWithState != null) { - Contract.Assert(sharedPStateFlags != null); + Debug.Assert(sharedPStateFlags != null); state = new ParallelLoopState32(sharedPStateFlags); } else if (bodyWithLocal != null) { - Contract.Assert(sharedPStateFlags != null); + Debug.Assert(sharedPStateFlags != null); state = new ParallelLoopState32(sharedPStateFlags); if (localInit != null) { @@ -1346,9 +1345,9 @@ namespace System.Threading.Tasks Func<long, ParallelLoopState, TLocal, TLocal> bodyWithLocal, Func<TLocal> localInit, Action<TLocal> localFinally) { - Contract.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithLocal == null ? 0 : 1)) == 1, + Debug.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithLocal == null ? 0 : 1)) == 1, "expected exactly one body function to be supplied"); - Contract.Assert(bodyWithLocal != null || (localInit == null && localFinally == null), + Debug.Assert(bodyWithLocal != null || (localInit == null && localFinally == null), "thread local functions should only be supplied for loops w/ thread local bodies"); // Instantiate our result. Specifics will be filled in later. @@ -1471,12 +1470,12 @@ namespace System.Threading.Tasks if (bodyWithState != null) { - Contract.Assert(sharedPStateFlags != null); + Debug.Assert(sharedPStateFlags != null); state = new ParallelLoopState64(sharedPStateFlags); } else if (bodyWithLocal != null) { - Contract.Assert(sharedPStateFlags != null); + Debug.Assert(sharedPStateFlags != null); state = new ParallelLoopState64(sharedPStateFlags); // If a thread-local selector was supplied, invoke it. Otherwise, use the default. @@ -1656,11 +1655,11 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } return ForEachWorker<TSource, object>( @@ -1701,15 +1700,15 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForEachWorker<TSource, object>( @@ -1741,11 +1740,11 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } return ForEachWorker<TSource, object>( @@ -1788,15 +1787,15 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForEachWorker<TSource, object>( @@ -1828,11 +1827,11 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } return ForEachWorker<TSource, object>( @@ -1875,15 +1874,15 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForEachWorker<TSource, object>( @@ -1936,19 +1935,19 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } return ForEachWorker<TSource, TLocal>( @@ -2013,23 +2012,23 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForEachWorker<TSource, TLocal>( @@ -2082,19 +2081,19 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } return ForEachWorker<TSource, TLocal>( @@ -2158,23 +2157,23 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return ForEachWorker<TSource, TLocal>( @@ -2214,10 +2213,10 @@ namespace System.Threading.Tasks Func<TSource, ParallelLoopState, long, TLocal, TLocal> bodyWithEverything, Func<TLocal> localInit, Action<TLocal> localFinally) { - Contract.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + + Debug.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithStateAndIndex == null ? 0 : 1) + (bodyWithStateAndLocal == null ? 0 : 1) + (bodyWithEverything == null ? 0 : 1)) == 1, "expected exactly one body function to be supplied"); - Contract.Assert((bodyWithStateAndLocal != null) || (bodyWithEverything != null) || (localInit == null && localFinally == null), + Debug.Assert((bodyWithStateAndLocal != null) || (bodyWithEverything != null) || (localInit == null && localFinally == null), "thread local functions should only be supplied for loops w/ thread local bodies"); // Before getting started, do a quick peek to see if we have been canceled already @@ -2278,8 +2277,8 @@ namespace System.Threading.Tasks Func<TSource, ParallelLoopState, long, TLocal, TLocal> bodyWithEverything, Func<TLocal> localInit, Action<TLocal> localFinally) { - Contract.Assert(array != null); - Contract.Assert(parallelOptions != null, "ForEachWorker(array): parallelOptions is null"); + Debug.Assert(array != null); + Debug.Assert(parallelOptions != null, "ForEachWorker(array): parallelOptions is null"); int from = array.GetLowerBound(0); int to = array.GetUpperBound(0) + 1; @@ -2337,8 +2336,8 @@ namespace System.Threading.Tasks Func<TSource, ParallelLoopState, long, TLocal, TLocal> bodyWithEverything, Func<TLocal> localInit, Action<TLocal> localFinally) { - Contract.Assert(list != null); - Contract.Assert(parallelOptions != null, "ForEachWorker(list): parallelOptions is null"); + Debug.Assert(list != null); + Debug.Assert(parallelOptions != null, "ForEachWorker(list): parallelOptions is null"); if (body != null) { @@ -2416,11 +2415,11 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } return PartitionerForEachWorker<TSource, object>(source, s_defaultParallelOptions, body, null, null, null, null, null, null); @@ -2475,11 +2474,11 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } return PartitionerForEachWorker<TSource, object>(source, s_defaultParallelOptions, null, body, null, null, null, null, null); @@ -2537,11 +2536,11 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (!source.KeysNormalized) @@ -2621,19 +2620,19 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } return PartitionerForEachWorker<TSource, TLocal>(source, s_defaultParallelOptions, null, null, null, body, null, localInit, localFinally); @@ -2711,19 +2710,19 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } if (!source.KeysNormalized) @@ -2793,15 +2792,15 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return PartitionerForEachWorker<TSource, object>(source, parallelOptions, body, null, null, null, null, null, null); @@ -2868,15 +2867,15 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return PartitionerForEachWorker<TSource, object>(source, parallelOptions, null, body, null, null, null, null, null); @@ -2946,15 +2945,15 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } if (!source.KeysNormalized) @@ -3046,23 +3045,23 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } return PartitionerForEachWorker<TSource, TLocal>(source, parallelOptions, null, null, null, body, null, localInit, localFinally); @@ -3152,23 +3151,23 @@ namespace System.Threading.Tasks { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (body == null) { - throw new ArgumentNullException("body"); + throw new ArgumentNullException(nameof(body)); } if (localInit == null) { - throw new ArgumentNullException("localInit"); + throw new ArgumentNullException(nameof(localInit)); } if (localFinally == null) { - throw new ArgumentNullException("localFinally"); + throw new ArgumentNullException(nameof(localFinally)); } if (parallelOptions == null) { - throw new ArgumentNullException("parallelOptions"); + throw new ArgumentNullException(nameof(parallelOptions)); } if (!source.KeysNormalized) @@ -3191,14 +3190,14 @@ namespace System.Threading.Tasks Func<TLocal> localInit, Action<TLocal> localFinally) { - Contract.Assert(((simpleBody == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + + Debug.Assert(((simpleBody == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithStateAndIndex == null ? 0 : 1) + (bodyWithStateAndLocal == null ? 0 : 1) + (bodyWithEverything == null ? 0 : 1)) == 1, "PartitionForEach: expected exactly one body function to be supplied"); - Contract.Assert((bodyWithStateAndLocal != null) || (bodyWithEverything != null) || (localInit == null && localFinally == null), + Debug.Assert((bodyWithStateAndLocal != null) || (bodyWithEverything != null) || (localInit == null && localFinally == null), "PartitionForEach: thread local functions should only be supplied for loops w/ thread local bodies"); OrderablePartitioner<TSource> orderedSource = source as OrderablePartitioner<TSource>; - Contract.Assert((orderedSource != null) || (bodyWithStateAndIndex == null && bodyWithEverything == null), + Debug.Assert((orderedSource != null) || (bodyWithStateAndIndex == null && bodyWithEverything == null), "PartitionForEach: bodies with indices are only allowable for OrderablePartitioner"); if (!source.SupportsDynamicPartitions) @@ -3401,7 +3400,7 @@ namespace System.Threading.Tasks else if (bodyWithStateAndLocal != null) localValue = bodyWithStateAndLocal(t, state, localValue); else - Contract.Assert(false, "PartitionerForEach: illegal body type in Partitioner handler"); + Debug.Assert(false, "PartitionerForEach: illegal body type in Partitioner handler"); // Any break, stop or exception causes us to halt @@ -3576,7 +3575,7 @@ namespace System.Threading.Tasks public bool LimitExceeded() { - Contract.Assert(m_timeLimit != 0, "Probably the default initializer for LoopTimer was used somewhere"); + Debug.Assert(m_timeLimit != 0, "Probably the default initializer for LoopTimer was used somewhere"); // comparing against the next expected time saves an addition operation here // Also we omit the comparison for wrap around here. The only side effect is one extra early yield every 38 days. diff --git a/src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs b/src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs index 4db3a9d105..6a62cf8977 100644 --- a/src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs +++ b/src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs @@ -26,7 +26,6 @@ namespace System.Threading.Tasks /// Enables iterations of <see cref="T:System.Threading.Tasks.Parallel"/> loops to interact with /// other iterations. /// </summary> - [HostProtection(Synchronization = true, ExternalThreading = true)] [DebuggerDisplay("ShouldExitCurrentIteration = {ShouldExitCurrentIteration}")] public class ParallelLoopState { @@ -47,7 +46,7 @@ namespace System.Threading.Tasks { get { - Contract.Assert(false); + Debug.Assert(false); throw new NotSupportedException( Environment.GetResourceString("ParallelState_NotSupportedException_UnsupportedMethod")); } @@ -104,7 +103,7 @@ namespace System.Threading.Tasks { get { - Contract.Assert(false); + Debug.Assert(false); throw new NotSupportedException( Environment.GetResourceString("ParallelState_NotSupportedException_UnsupportedMethod")); } @@ -152,7 +151,7 @@ namespace System.Threading.Tasks // Internal/virtual support for Break(). internal virtual void InternalBreak() { - Contract.Assert(false); + Debug.Assert(false); throw new NotSupportedException( Environment.GetResourceString("ParallelState_NotSupportedException_UnsupportedMethod")); } diff --git a/src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs b/src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs index c4b66c41a9..49f61a6614 100644 --- a/src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs +++ b/src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs @@ -12,6 +12,7 @@ using System; using System.Threading; +using System.Diagnostics; using System.Diagnostics.Contracts; #pragma warning disable 0420 @@ -160,7 +161,7 @@ namespace System.Threading.Tasks bool bRetVal = FindNewWork(out nFromInclusiveLocal, out nToExclusiveLocal); - Contract.Assert((nFromInclusiveLocal <= Int32.MaxValue) && (nFromInclusiveLocal >= Int32.MinValue) && + Debug.Assert((nFromInclusiveLocal <= Int32.MaxValue) && (nFromInclusiveLocal >= Int32.MinValue) && (nToExclusiveLocal <= Int32.MaxValue) && (nToExclusiveLocal >= Int32.MinValue)); // convert to 32 bit before returning @@ -218,7 +219,7 @@ namespace System.Threading.Tasks // // find the actual number of index ranges we will need // - Contract.Assert((uSpan / uRangeSize) < Int32.MaxValue); + Debug.Assert((uSpan / uRangeSize) < Int32.MaxValue); int nNumRanges = (int)(uSpan / uRangeSize); @@ -251,7 +252,7 @@ namespace System.Threading.Tasks nCurrentIndex > nToExclusive) { // this should only happen at the last index - Contract.Assert(i == nNumRanges - 1); + Debug.Assert(i == nNumRanges - 1); nCurrentIndex = nToExclusive; } @@ -267,7 +268,7 @@ namespace System.Threading.Tasks /// </summary> internal RangeWorker RegisterNewWorker() { - Contract.Assert(m_indexRanges != null && m_indexRanges.Length != 0); + Debug.Assert(m_indexRanges != null && m_indexRanges.Length != 0); int nInitialRange = (Interlocked.Increment(ref m_nCurrentIndexRangeToAssign) - 1) % m_indexRanges.Length; diff --git a/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs b/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs index 462ee0a9bd..6b9dfbbe37 100644 --- a/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs +++ b/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs @@ -140,10 +140,10 @@ namespace System.Threading.Tasks internal SingleProducerSingleConsumerQueue() { // Validate constants in ctor rather than in an explicit cctor that would cause perf degradation - Contract.Assert(INIT_SEGMENT_SIZE > 0, "Initial segment size must be > 0."); - Contract.Assert((INIT_SEGMENT_SIZE & (INIT_SEGMENT_SIZE - 1)) == 0, "Initial segment size must be a power of 2"); - Contract.Assert(INIT_SEGMENT_SIZE <= MAX_SEGMENT_SIZE, "Initial segment size should be <= maximum."); - Contract.Assert(MAX_SEGMENT_SIZE < Int32.MaxValue / 2, "Max segment size * 2 must be < Int32.MaxValue, or else overflow could occur."); + Debug.Assert(INIT_SEGMENT_SIZE > 0, "Initial segment size must be > 0."); + Debug.Assert((INIT_SEGMENT_SIZE & (INIT_SEGMENT_SIZE - 1)) == 0, "Initial segment size must be a power of 2"); + Debug.Assert(INIT_SEGMENT_SIZE <= MAX_SEGMENT_SIZE, "Initial segment size should be <= maximum."); + Debug.Assert(MAX_SEGMENT_SIZE < Int32.MaxValue / 2, "Max segment size * 2 must be < Int32.MaxValue, or else overflow could occur."); // Initialize the queue m_head = m_tail = new Segment(INIT_SEGMENT_SIZE); @@ -183,7 +183,7 @@ namespace System.Threading.Tasks } int newSegmentSize = m_tail.m_array.Length << 1; // double size - Contract.Assert(newSegmentSize > 0, "The max size should always be small enough that we don't overflow."); + Debug.Assert(newSegmentSize > 0, "The max size should always be small enough that we don't overflow."); if (newSegmentSize > MAX_SEGMENT_SIZE) newSegmentSize = MAX_SEGMENT_SIZE; var newSegment = new Segment(newSegmentSize); @@ -456,7 +456,7 @@ namespace System.Threading.Tasks /// <remarks>The Count is not thread safe, so we need to acquire the lock.</remarks> int IProducerConsumerQueue<T>.GetCountSafe(object syncObj) { - Contract.Assert(syncObj != null, "The syncObj parameter is null."); + Debug.Assert(syncObj != null, "The syncObj parameter is null."); lock (syncObj) { return Count; diff --git a/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs b/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs index 5f79f30b35..325aa91b44 100644 --- a/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs +++ b/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs @@ -216,7 +216,6 @@ namespace System.Threading.Tasks /// <param name="OperationType">The kind of fork/join operation.</param> /// <param name="InclusiveFrom">The lower bound of the loop.</param> /// <param name="ExclusiveTo">The upper bound of the loop.</param> - [SecuritySafeCritical] [Event(PARALLELLOOPBEGIN_ID, Level = EventLevel.Informational, ActivityOptions=EventActivityOptions.Recursive, Task = TplEtwProvider.Tasks.Loop, Opcode = EventOpcode.Start)] public void ParallelLoopBegin( @@ -261,7 +260,6 @@ namespace System.Threading.Tasks /// <param name="OriginatingTaskID">The task ID.</param> /// <param name="ForkJoinContextID">The loop ID.</param> /// <param name="TotalIterations">the total number of iterations processed.</param> - [SecuritySafeCritical] [Event(PARALLELLOOPEND_ID, Level = EventLevel.Informational, Task = TplEtwProvider.Tasks.Loop, Opcode = EventOpcode.Stop)] public void ParallelLoopEnd( int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER @@ -298,7 +296,6 @@ namespace System.Threading.Tasks /// <param name="ForkJoinContextID">The invoke ID.</param> /// <param name="OperationType">The kind of fork/join operation.</param> /// <param name="ActionCount">The number of actions being invoked.</param> - [SecuritySafeCritical] [Event(PARALLELINVOKEBEGIN_ID, Level = EventLevel.Informational, ActivityOptions=EventActivityOptions.Recursive, Task = TplEtwProvider.Tasks.Invoke, Opcode = EventOpcode.Start)] public void ParallelInvokeBegin( @@ -412,7 +409,6 @@ namespace System.Threading.Tasks /// <param name="TaskID">The task ID.</param> /// <param name="CreatingTaskID">The task ID</param> /// <param name="TaskCreationOptions">The options used to create the task.</param> - [SecuritySafeCritical] [Event(TASKSCHEDULED_ID, Task = Tasks.TaskScheduled, Version=1, Opcode = EventOpcode.Send, Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)] public void TaskScheduled( @@ -475,7 +471,6 @@ namespace System.Threading.Tasks /// <param name="OriginatingTaskID">The task ID.</param> /// <param name="TaskID">The task ID.</param> /// <param name="IsExceptional">Whether the task completed due to an error.</param> - [SecuritySafeCritical] [Event(TASKCOMPLETED_ID, Version=1, Level = EventLevel.Informational, Keywords = Keywords.TaskStops)] public void TaskCompleted( @@ -513,7 +508,6 @@ namespace System.Threading.Tasks /// <param name="ContinueWithTaskID">If known, if 'TaskID' has a 'continueWith' task, mention give its ID here. /// 0 means unknown. This allows better visualization of the common sequential chaining case.</param> /// </summary> - [SecuritySafeCritical] [Event(TASKWAITBEGIN_ID, Version=3, Task = TplEtwProvider.Tasks.TaskWait, Opcode = EventOpcode.Send, Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)] public void TaskWaitBegin( @@ -600,7 +594,6 @@ namespace System.Threading.Tasks /// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param> /// <param name="OriginatingTaskID">The task ID.</param> /// <param name="TaskID">The activityId for the continuation.</param> - [SecuritySafeCritical] [Event(AWAITTASKCONTINUATIONSCHEDULED_ID, Task = Tasks.AwaitTaskContinuationScheduled, Opcode = EventOpcode.Send, Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)] public void AwaitTaskContinuationScheduled( @@ -629,7 +622,6 @@ namespace System.Threading.Tasks } } - [SecuritySafeCritical] [Event(TRACEOPERATIONSTART_ID, Version=1, Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityOperation)] public void TraceOperationBegin(int TaskID, string OperationName, long RelatedContext) @@ -655,7 +647,6 @@ namespace System.Threading.Tasks } } - [SecuritySafeCritical] [Event(TRACEOPERATIONRELATION_ID, Version=1, Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityRelation)] public void TraceOperationRelation(int TaskID, CausalityRelation Relation) @@ -664,7 +655,6 @@ namespace System.Threading.Tasks WriteEvent(TRACEOPERATIONRELATION_ID, TaskID,(int) Relation); // optmized overload for this exists } - [SecuritySafeCritical] [Event(TRACEOPERATIONSTOP_ID, Version=1, Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityOperation)] public void TraceOperationEnd(int TaskID, AsyncCausalityStatus Status) @@ -673,7 +663,6 @@ namespace System.Threading.Tasks WriteEvent(TRACEOPERATIONSTOP_ID, TaskID,(int) Status); // optmized overload for this exists } - [SecuritySafeCritical] [Event(TRACESYNCHRONOUSWORKSTART_ID, Version=1, Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalitySynchronousWork)] public void TraceSynchronousWorkBegin(int TaskID, CausalitySynchronousWork Work) @@ -682,7 +671,6 @@ namespace System.Threading.Tasks WriteEvent(TRACESYNCHRONOUSWORKSTART_ID, TaskID,(int) Work); // optmized overload for this exists } - [SecuritySafeCritical] [Event(TRACESYNCHRONOUSWORKSTOP_ID, Version=1, Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalitySynchronousWork)] public void TraceSynchronousWorkEnd(CausalitySynchronousWork Work) diff --git a/src/mscorlib/src/System/Threading/Tasks/Task.cs b/src/mscorlib/src/System/Threading/Tasks/Task.cs index 36f8401a4d..cf081f75fd 100644 --- a/src/mscorlib/src/System/Threading/Tasks/Task.cs +++ b/src/mscorlib/src/System/Threading/Tasks/Task.cs @@ -137,7 +137,6 @@ namespace System.Threading.Tasks /// InternalWait method serves a potential marker for when a Task is entering a wait operation. /// </para> /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] [DebuggerTypeProxy(typeof(SystemThreadingTasks_TaskDebugView))] [DebuggerDisplay("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}")] public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable @@ -152,7 +151,7 @@ namespace System.Threading.Tasks private volatile int m_taskId; // this task's unique ID. initialized only if it is ever requested - internal object m_action; // The body of the task. Might be Action<object>, Action<TState> or Action. Or possibly a Func. + internal Delegate m_action; // The body of the task. Might be Action<object>, Action<TState> or Action. Or possibly a Func. // If m_action is set to null it will indicate that we operate in the // "externally triggered completion" mode, which is exclusively meant // for the signalling Task<TResult> (aka. promise). In this mode, @@ -339,7 +338,7 @@ namespace System.Threading.Tasks // (action,TCO). It should always be true. internal Task(object state, TaskCreationOptions creationOptions, bool promiseStyle) { - Contract.Assert(promiseStyle, "Promise CTOR: promiseStyle was false"); + Debug.Assert(promiseStyle, "Promise CTOR: promiseStyle was false"); // Check the creationOptions. We allow the AttachedToParent option to be specified for promise tasks. // Also allow RunContinuationsAsynchronously because this is the constructor called by TCS @@ -580,7 +579,7 @@ namespace System.Threading.Tasks /// <param name="cancellationToken">A CancellationToken for the Task.</param> /// <param name="creationOptions">Options to customize behavior of Task.</param> /// <param name="internalOptions">Internal options to customize behavior of Task.</param> - internal void TaskConstructorCore(object action, object state, CancellationToken cancellationToken, + internal void TaskConstructorCore(Delegate action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) { m_action = action; @@ -609,7 +608,7 @@ namespace System.Threading.Tasks InternalTaskOptions.ContinuationTask | InternalTaskOptions.LazyCancellation | InternalTaskOptions.QueuedByRuntime)); - Contract.Assert(illegalInternalOptions == 0, "TaskConstructorCore: Illegal internal options"); + Debug.Assert(illegalInternalOptions == 0, "TaskConstructorCore: Illegal internal options"); #endif // Throw exception if the user specifies both LongRunning and SelfReplicating @@ -620,8 +619,8 @@ namespace System.Threading.Tasks } // Assign options to m_stateAndOptionsFlag. - Contract.Assert(m_stateFlags == 0, "TaskConstructorCore: non-zero m_stateFlags"); - Contract.Assert((((int)creationOptions) | OptionsMask) == OptionsMask, "TaskConstructorCore: options take too many bits"); + Debug.Assert(m_stateFlags == 0, "TaskConstructorCore: non-zero m_stateFlags"); + Debug.Assert((((int)creationOptions) | OptionsMask) == OptionsMask, "TaskConstructorCore: options take too many bits"); var tmpFlags = (int)creationOptions | (int)internalOptions; if ((m_action == null) || ((internalOptions & InternalTaskOptions.ContinuationTask) != 0)) { @@ -649,7 +648,7 @@ namespace System.Threading.Tasks // we need to do this as the very last thing in the construction path, because the CT registration could modify m_stateFlags if (cancellationToken.CanBeCanceled) { - Contract.Assert((internalOptions & + Debug.Assert((internalOptions & (InternalTaskOptions.ChildReplica | InternalTaskOptions.SelfReplicating | InternalTaskOptions.ContinuationTask)) == 0, "TaskConstructorCore: Did not expect to see cancelable token for replica/replicating or continuation task."); @@ -743,7 +742,7 @@ namespace System.Threading.Tasks antecedentTask.RemoveContinuation(continuation); } } - Contract.Assert(targetTask != null, + Debug.Assert(targetTask != null, "targetTask should have been non-null, with the supplied argument being a task or a tuple containing one"); targetTask.InternalCancel(false); } @@ -753,7 +752,7 @@ namespace System.Threading.Tasks { get { - Delegate d = (Delegate)m_action; + Delegate d = m_action; return d != null ? d.Method.ToString() : "{null}"; } } @@ -764,10 +763,9 @@ namespace System.Threading.Tasks /// </summary> /// <param name="stackMark">A stack crawl mark pointing to the frame of the caller.</param> - [SecuritySafeCritical] internal void PossiblyCaptureContext(ref StackCrawlMark stackMark) { - Contract.Assert(m_contingentProperties == null || m_contingentProperties.m_capturedContext == null, + Debug.Assert(m_contingentProperties == null || m_contingentProperties.m_capturedContext == null, "Captured an ExecutionContext when one was already captured."); // In the legacy .NET 3.5 build, we don't have the optimized overload of Capture() @@ -791,7 +789,7 @@ namespace System.Threading.Tasks // a read of the volatile m_stateFlags field. internal static TaskCreationOptions OptionsMethod(int flags) { - Contract.Assert((OptionsMask & 1) == 1, "OptionsMask needs a shift in Options.get"); + Debug.Assert((OptionsMask & 1) == 1, "OptionsMask needs a shift in Options.get"); return (TaskCreationOptions)(flags & OptionsMask); } @@ -841,7 +839,7 @@ namespace System.Threading.Tasks /// <param name="enabled">true to set the bit; false to unset the bit.</param> internal void SetNotificationForWaitCompletion(bool enabled) { - Contract.Assert((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0, + Debug.Assert((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0, "Should only be used for promise-style tasks"); // hasn't been vetted on other kinds as there hasn't been a need if (enabled) @@ -849,7 +847,7 @@ namespace System.Threading.Tasks // Atomically set the END_AWAIT_NOTIFICATION bit bool success = AtomicStateUpdate(TASK_STATE_WAIT_COMPLETION_NOTIFICATION, TASK_STATE_COMPLETED_MASK | TASK_STATE_COMPLETION_RESERVED); - Contract.Assert(success, "Tried to set enabled on completed Task"); + Debug.Assert(success, "Tried to set enabled on completed Task"); } else { @@ -886,7 +884,7 @@ namespace System.Threading.Tasks /// <returns>true if any of the tasks require notification; otherwise, false.</returns> internal static bool AnyTaskRequiresNotifyDebuggerOfWaitCompletion(Task[] tasks) { - Contract.Assert(tasks != null, "Expected non-null array of tasks"); + Debug.Assert(tasks != null, "Expected non-null array of tasks"); foreach (var task in tasks) { if (task != null && @@ -926,7 +924,7 @@ namespace System.Threading.Tasks // bit was unset between the time that it was checked and this method was called. // It's so remote a chance that it's worth having the assert to protect against misuse. bool isWaitNotificationEnabled = IsWaitNotificationEnabled; - Contract.Assert(isWaitNotificationEnabled, "Should only be called if the wait completion bit is set."); + Debug.Assert(isWaitNotificationEnabled, "Should only be called if the wait completion bit is set."); return isWaitNotificationEnabled; } } @@ -946,7 +944,7 @@ namespace System.Threading.Tasks // It's theoretically possible but extremely rare that this assert could fire because the // bit was unset between the time that it was checked and this method was called. // It's so remote a chance that it's worth having the assert to protect against misuse. - Contract.Assert(IsWaitNotificationEnabled, "Should only be called if the wait completion bit is set."); + Debug.Assert(IsWaitNotificationEnabled, "Should only be called if the wait completion bit is set."); // Now that we're notifying the debugger, clear the bit. The debugger should do this anyway, // but this adds a bit of protection in case it fails to, and given that the debugger is involved, @@ -991,7 +989,7 @@ namespace System.Threading.Tasks /// </summary> internal void AddNewChild() { - Contract.Assert(Task.InternalCurrent == this || this.IsSelfReplicatingRoot, "Task.AddNewChild(): Called from an external context"); + Debug.Assert(Task.InternalCurrent == this || this.IsSelfReplicatingRoot, "Task.AddNewChild(): Called from an external context"); var props = EnsureContingentPropertiesInitialized(); @@ -1014,10 +1012,10 @@ namespace System.Threading.Tasks // We need to subtract that child from m_completionCountdown, or the parent will never complete. internal void DisregardChild() { - Contract.Assert(Task.InternalCurrent == this, "Task.DisregardChild(): Called from an external context"); + Debug.Assert(Task.InternalCurrent == this, "Task.DisregardChild(): Called from an external context"); var props = EnsureContingentPropertiesInitialized(); - Contract.Assert(props.m_completionCountdown >= 2, "Task.DisregardChild(): Expected parent count to be >= 2"); + Debug.Assert(props.m_completionCountdown >= 2, "Task.DisregardChild(): Expected parent count to be >= 2"); Interlocked.Decrement(ref props.m_completionCountdown); } @@ -1161,7 +1159,6 @@ namespace System.Threading.Tasks // // Internal version of RunSynchronously that allows not waiting for completion. // - [SecuritySafeCritical] // Needed for QueueTask internal void InternalRunSynchronously(TaskScheduler scheduler, bool waitForCompletion) { Contract.Requires(scheduler != null, "Task.InternalRunSynchronously(): null TaskScheduler"); @@ -1235,7 +1232,7 @@ namespace System.Threading.Tasks // Mark ourselves as "handled" to avoid crashing the finalizer thread if the caller neglects to // call Wait() on this task. // m_contingentProperties.m_exceptionsHolder *should* already exist after AddException() - Contract.Assert( + Debug.Assert( (m_contingentProperties != null) && (m_contingentProperties.m_exceptionsHolder != null) && (m_contingentProperties.m_exceptionsHolder.ContainsFaultList), @@ -1252,7 +1249,7 @@ namespace System.Threading.Tasks } else { - Contract.Assert((m_stateFlags & TASK_STATE_CANCELED) != 0, "Task.RunSynchronously: expected TASK_STATE_CANCELED to be set"); + Debug.Assert((m_stateFlags & TASK_STATE_CANCELED) != 0, "Task.RunSynchronously: expected TASK_STATE_CANCELED to be set"); // Can't call this method on canceled task. ThrowHelper.ThrowInvalidOperationException(ExceptionResource.Task_RunSynchronously_TaskCompleted); } @@ -1403,7 +1400,7 @@ namespace System.Threading.Tasks // Only return an exception in faulted state (skip manufactured exceptions) // A "benevolent" race condition makes it possible to return null when IsFaulted is // true (i.e., if IsFaulted is set just after the check to IsFaulted above). - Contract.Assert((e == null) || IsFaulted, "Task.Exception_get(): returning non-null value when not Faulted"); + Debug.Assert((e == null) || IsFaulted, "Task.Exception_get(): returning non-null value when not Faulted"); return e; } @@ -1884,11 +1881,10 @@ namespace System.Threading.Tasks /// underneath us. If false, TASK_STATE_STARTED bit is OR-ed right in. This /// allows us to streamline things a bit for StartNew(), where competing cancellations /// are not a problem.</param> - [SecuritySafeCritical] // Needed for QueueTask internal void ScheduleAndStart(bool needsProtection) { - Contract.Assert(m_taskScheduler != null, "expected a task scheduler to have been selected"); - Contract.Assert((m_stateFlags & TASK_STATE_STARTED) == 0, "task has already started"); + Debug.Assert(m_taskScheduler != null, "expected a task scheduler to have been selected"); + Debug.Assert((m_stateFlags & TASK_STATE_STARTED) == 0, "task has already started"); // Set the TASK_STATE_STARTED bit if (needsProtection) @@ -1912,7 +1908,7 @@ namespace System.Threading.Tasks if (AsyncCausalityTracer.LoggingOn && (Options & (TaskCreationOptions)InternalTaskOptions.ContinuationTask) == 0) { //For all other task than TaskContinuations we want to log. TaskContinuations log in their constructor - AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "Task: "+((Delegate)m_action).Method.Name, 0); + AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "Task: " + m_action.Method.Name, 0); } @@ -1942,7 +1938,7 @@ namespace System.Threading.Tasks if ((Options & (TaskCreationOptions)InternalTaskOptions.ContinuationTask) == 0) { // m_contingentProperties.m_exceptionsHolder *should* already exist after AddException() - Contract.Assert( + Debug.Assert( (m_contingentProperties != null) && (m_contingentProperties.m_exceptionsHolder != null) && (m_contingentProperties.m_exceptionsHolder.ContainsFaultList), @@ -1981,13 +1977,13 @@ namespace System.Threading.Tasks var eoAsEdi = exceptionObject as ExceptionDispatchInfo; var eoAsEnumerableEdi = exceptionObject as IEnumerable<ExceptionDispatchInfo>; - Contract.Assert( + Debug.Assert( eoAsException != null || eoAsEnumerableException != null || eoAsEdi != null || eoAsEnumerableEdi != null, "Task.AddException: Expected an Exception, ExceptionDispatchInfo, or an IEnumerable<> of one of those"); var eoAsOce = exceptionObject as OperationCanceledException; - Contract.Assert( + Debug.Assert( !representsCancellation || eoAsOce != null || (eoAsEdi != null && eoAsEdi.SourceException is OperationCanceledException), @@ -2078,7 +2074,7 @@ namespace System.Threading.Tasks { // There are exceptions; get the aggregate and optionally add the canceled // exception to the aggregate (if applicable). - Contract.Assert(m_contingentProperties != null); // ExceptionRecorded ==> m_contingentProperties != null + Debug.Assert(m_contingentProperties != null); // ExceptionRecorded ==> m_contingentProperties != null // No need to lock around this, as other logic prevents the consumption of exceptions // before they have been completely processed. @@ -2097,7 +2093,7 @@ namespace System.Threading.Tasks internal ReadOnlyCollection<ExceptionDispatchInfo> GetExceptionDispatchInfos() { bool exceptionsAvailable = IsFaulted && ExceptionRecorded; - Contract.Assert(exceptionsAvailable, "Must only be used when the task has faulted with exceptions."); + Debug.Assert(exceptionsAvailable, "Must only be used when the task has faulted with exceptions."); return exceptionsAvailable ? m_contingentProperties.m_exceptionsHolder.GetExceptionDispatchInfos() : new ReadOnlyCollection<ExceptionDispatchInfo>(new ExceptionDispatchInfo[0]); @@ -2107,7 +2103,7 @@ namespace System.Threading.Tasks /// <returns>The ExceptionDispatchInfo. May be null if no OCE was stored for the task.</returns> internal ExceptionDispatchInfo GetCancellationExceptionDispatchInfo() { - Contract.Assert(IsCanceled, "Must only be used when the task has canceled."); + Debug.Assert(IsCanceled, "Must only be used when the task has canceled."); return Volatile.Read(ref m_contingentProperties)?.m_exceptionsHolder?.GetCancellationExceptionDispatchInfo(); // may be null } @@ -2344,7 +2340,7 @@ namespace System.Threading.Tasks Contract.Requires(childTask != null); Contract.Requires(childTask.IsCompleted, "ProcessChildCompletion was called for an uncompleted task"); - Contract.Assert(childTask.m_contingentProperties?.m_parent == this, "ProcessChildCompletion should only be called for a child of this task"); + Debug.Assert(childTask.m_contingentProperties?.m_parent == this, "ProcessChildCompletion should only be called for a child of this task"); var props = Volatile.Read(ref m_contingentProperties); @@ -2404,11 +2400,11 @@ namespace System.Threading.Tasks { // Ensure any exceptions thrown by children are added to the parent. // In doing this, we are implicitly marking children as being "handled". - Contract.Assert(task.IsCompleted, "Expected all tasks in list to be completed"); + Debug.Assert(task.IsCompleted, "Expected all tasks in list to be completed"); if (task.IsFaulted && !task.IsExceptionObservedByParent) { TaskExceptionHolder exceptionHolder = Volatile.Read(ref task.m_contingentProperties).m_exceptionsHolder; - Contract.Assert(exceptionHolder != null); + Debug.Assert(exceptionHolder != null); // No locking necessary since child task is finished adding exceptions // and concurrent CreateExceptionObject() calls do not constitute @@ -2435,7 +2431,7 @@ namespace System.Threading.Tasks /// <param name="delegateRan">Whether the delegate was executed.</param> internal void FinishThreadAbortedTask(bool bTAEAddedToExceptionHolder, bool delegateRan) { - Contract.Assert(!bTAEAddedToExceptionHolder || m_contingentProperties?.m_exceptionsHolder != null, + Debug.Assert(!bTAEAddedToExceptionHolder || m_contingentProperties?.m_exceptionsHolder != null, "FinishThreadAbortedTask() called on a task whose exception holder wasn't initialized"); // this will only be false for non-root self replicating task copies, because all of their exceptions go to the root task. @@ -2671,7 +2667,6 @@ namespace System.Threading.Tasks /// IThreadPoolWorkItem override, which is the entry function for this task when the TP scheduler decides to run it. /// /// </summary> - [SecurityCritical] void IThreadPoolWorkItem.ExecuteWorkItem() { ExecuteEntry(false); @@ -2681,7 +2676,6 @@ namespace System.Threading.Tasks /// The ThreadPool calls this if a ThreadAbortException is thrown while trying to execute this workitem. This may occur /// before Task would otherwise be able to observe it. /// </summary> - [SecurityCritical] void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { // If the task has marked itself as Completed, then it either a) already observed this exception (so we shouldn't handle it here) @@ -2700,7 +2694,6 @@ namespace System.Threading.Tasks /// </summary> /// <param name="bPreventDoubleExecution"> Performs atomic updates to prevent double execution. Should only be set to true /// in codepaths servicing user provided TaskSchedulers. The ConcRT or ThreadPool schedulers don't need this. </param> - [SecuritySafeCritical] internal bool ExecuteEntry(bool bPreventDoubleExecution) { if (bPreventDoubleExecution || ((Options & (TaskCreationOptions)InternalTaskOptions.SelfReplicating) != 0)) @@ -2742,7 +2735,6 @@ namespace System.Threading.Tasks } // A trick so we can refer to the TLS slot with a byref. - [SecurityCritical] private void ExecuteWithThreadLocal(ref Task currentTaskSlot) { // Remember the current task so we can restore it after running, and then @@ -2819,14 +2811,12 @@ namespace System.Threading.Tasks } // Cached callback delegate that's lazily initialized due to ContextCallback being SecurityCritical - [SecurityCritical] private static ContextCallback s_ecCallback; - [SecurityCritical] private static void ExecutionContextCallback(object obj) { Task task = obj as Task; - Contract.Assert(task != null, "expected a task object"); + Debug.Assert(task != null, "expected a task object"); task.Execute(); } @@ -2837,7 +2827,7 @@ namespace System.Threading.Tasks internal virtual void InnerInvoke() { // Invoke the delegate - Contract.Assert(m_action != null, "Null action in InnerInvoke()"); + Debug.Assert(m_action != null, "Null action in InnerInvoke()"); var action = m_action as Action; if (action != null) { @@ -2850,7 +2840,7 @@ namespace System.Threading.Tasks actionWithState(m_stateObject); return; } - Contract.Assert(false, "Invalid m_action in Task"); + Debug.Assert(false, "Invalid m_action in Task"); } /// <summary> @@ -2929,7 +2919,6 @@ namespace System.Threading.Tasks /// <param name="flowExecutionContext">Whether to flow ExecutionContext across the await.</param> /// <param name="stackMark">A stack crawl mark tied to execution context.</param> /// <exception cref="System.InvalidOperationException">The awaiter was not properly initialized.</exception> - [SecurityCritical] internal void SetContinuationForAwait( Action continuationAction, bool continueOnCapturedContext, bool flowExecutionContext, ref StackCrawlMark stackMark) { @@ -2986,7 +2975,7 @@ namespace System.Threading.Tasks } else { - Contract.Assert(!flowExecutionContext, "We already determined we're not required to flow context."); + Debug.Assert(!flowExecutionContext, "We already determined we're not required to flow context."); if (!AddTaskContinuation(continuationAction, addBeforeOthers: false)) AwaitTaskContinuation.UnsafeScheduleAction(continuationAction, this); } @@ -3019,7 +3008,7 @@ namespace System.Threading.Tasks Wait(Timeout.Infinite, default(CancellationToken)); #if DEBUG - Contract.Assert(waitResult, "expected wait to succeed"); + Debug.Assert(waitResult, "expected wait to succeed"); #endif } @@ -3154,7 +3143,7 @@ namespace System.Threading.Tasks ThrowIfExceptional(true); } - Contract.Assert((m_stateFlags & TASK_STATE_FAULTED) == 0, "Task.Wait() completing when in Faulted state."); + Debug.Assert((m_stateFlags & TASK_STATE_FAULTED) == 0, "Task.Wait() completing when in Faulted state."); return true; } @@ -3230,7 +3219,7 @@ namespace System.Threading.Tasks } } - Contract.Assert(IsCompleted || millisecondsTimeout != Timeout.Infinite); + Debug.Assert(IsCompleted || millisecondsTimeout != Timeout.Infinite); // ETW event for Task Wait End if (etwIsEnabled) @@ -3358,7 +3347,6 @@ namespace System.Threading.Tasks /// For custom schedulers we also attempt an atomic state transition. /// </param> /// <returns>true if the task was successfully canceled; otherwise, false.</returns> - [SecuritySafeCritical] internal bool InternalCancel(bool bCancelNonExecutingOnly) { Contract.Requires((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) == 0, "Task.InternalCancel() did not expect promise-style task"); @@ -3426,7 +3414,7 @@ namespace System.Threading.Tasks if (bPopSucceeded) { // hitting this would mean something wrong with the AtomicStateUpdate above - Contract.Assert(!mustCleanup, "Possibly an invalid state transition call was made in InternalCancel()"); + Debug.Assert(!mustCleanup, "Possibly an invalid state transition call was made in InternalCancel()"); // Include TASK_STATE_DELEGATE_INVOKED in "illegal" bits to protect against the situation where // TS.TryDequeue() returns true but the task is still left on the queue. @@ -3466,8 +3454,8 @@ namespace System.Threading.Tasks { RecordInternalCancellationRequest(); - Contract.Assert((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0, "Task.RecordInternalCancellationRequest(CancellationToken) only valid for promise-style task"); - Contract.Assert(m_contingentProperties.m_cancellationToken == default(CancellationToken)); + Debug.Assert((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0, "Task.RecordInternalCancellationRequest(CancellationToken) only valid for promise-style task"); + Debug.Assert(m_contingentProperties.m_cancellationToken == default(CancellationToken)); // Store the supplied cancellation token as this task's token. // Waiting on this task will then result in an OperationCanceledException containing this token. @@ -3492,11 +3480,11 @@ namespace System.Threading.Tasks if (oce == null) { var edi = cancellationException as ExceptionDispatchInfo; - Contract.Assert(edi != null, "Expected either an OCE or an EDI"); + Debug.Assert(edi != null, "Expected either an OCE or an EDI"); oce = edi.SourceException as OperationCanceledException; - Contract.Assert(oce != null, "Expected EDI to contain an OCE"); + Debug.Assert(oce != null, "Expected EDI to contain an OCE"); } - Contract.Assert(oce.CancellationToken == tokenToRecord, + Debug.Assert(oce.CancellationToken == tokenToRecord, "Expected OCE's token to match the provided token."); #endif AddException(cancellationException, representsCancellation: true); @@ -3507,10 +3495,10 @@ namespace System.Threading.Tasks // And this method should be called at most once per task. internal void CancellationCleanupLogic() { - Contract.Assert((m_stateFlags & (TASK_STATE_CANCELED | TASK_STATE_COMPLETION_RESERVED)) != 0, "Task.CancellationCleanupLogic(): Task not canceled or reserved."); + Debug.Assert((m_stateFlags & (TASK_STATE_CANCELED | TASK_STATE_COMPLETION_RESERVED)) != 0, "Task.CancellationCleanupLogic(): Task not canceled or reserved."); // I'd like to do this, but there is a small window for a race condition. If someone calls Wait() between InternalCancel() and // here, that will set m_completionEvent, leading to a meaningless/harmless assertion. - //Contract.Assert((m_completionEvent == null) || !m_completionEvent.IsSet, "Task.CancellationCleanupLogic(): Completion event already set."); + //Debug.Assert((m_completionEvent == null) || !m_completionEvent.IsSet, "Task.CancellationCleanupLogic(): Completion event already set."); // This may have been set already, but we need to make sure. Interlocked.Exchange(ref m_stateFlags, m_stateFlags | TASK_STATE_CANCELED); @@ -3541,8 +3529,8 @@ namespace System.Threading.Tasks /// </summary> private void SetCancellationAcknowledged() { - Contract.Assert(this == Task.InternalCurrent, "SetCancellationAcknowledged() should only be called while this is still the current task"); - Contract.Assert(IsCancellationRequested, "SetCancellationAcknowledged() should not be called if the task's CT wasn't signaled"); + Debug.Assert(this == Task.InternalCurrent, "SetCancellationAcknowledged() should only be called while this is still the current task"); + Debug.Assert(IsCancellationRequested, "SetCancellationAcknowledged() should not be called if the task's CT wasn't signaled"); m_stateFlags |= TASK_STATE_CANCELLATIONACKNOWLEDGED; } @@ -3558,7 +3546,6 @@ namespace System.Threading.Tasks /// <summary> /// Runs all of the continuations, as appropriate. /// </summary> - [SecuritySafeCritical] // for AwaitTaskContinuation.RunOrScheduleAction internal void FinishContinuations() { // Atomically store the fact that this task is completing. From this point on, the adding of continuations will @@ -3684,7 +3671,7 @@ namespace System.Threading.Tasks // Otherwise, it must be an ITaskCompletionAction, so invoke it. else { - Contract.Assert(currentContinuation is ITaskCompletionAction, "Expected continuation element to be Action, TaskContinuation, or ITaskContinuationAction"); + Debug.Assert(currentContinuation is ITaskCompletionAction, "Expected continuation element to be Action, TaskContinuation, or ITaskContinuationAction"); var action = (ITaskCompletionAction)currentContinuation; if (bCanInlineContinuations || !action.InvokeMayRunArbitraryCode) @@ -4730,7 +4717,7 @@ namespace System.Threading.Tasks // m_continuationObject is guaranteed at this point to be either a List or // s_taskCompletionSentinel. List<object> list = m_continuationObject as List<object>; - Contract.Assert((list != null) || (m_continuationObject == s_taskCompletionSentinel), + Debug.Assert((list != null) || (m_continuationObject == s_taskCompletionSentinel), "Expected m_continuationObject to be list or sentinel"); // If list is null, it can only mean that s_taskCompletionSentinel has been exchanged @@ -4873,7 +4860,7 @@ namespace System.Threading.Tasks WaitAll(tasks, Timeout.Infinite); #if DEBUG - Contract.Assert(waitResult, "expected wait to succeed"); + Debug.Assert(waitResult, "expected wait to succeed"); #endif } @@ -5134,7 +5121,7 @@ namespace System.Threading.Tasks // Now gather up and throw all of the exceptions. foreach (var task in tasks) AddExceptionsForCompletedTask(ref exceptions, task); - Contract.Assert(exceptions != null, "Should have seen at least one exception"); + Debug.Assert(exceptions != null, "Should have seen at least one exception"); ThrowHelper.ThrowAggregateException(exceptions); } @@ -5159,8 +5146,8 @@ namespace System.Threading.Tasks /// <returns>true if all of the tasks completed; otherwise, false.</returns> private static bool WaitAllBlockingCore(List<Task> tasks, int millisecondsTimeout, CancellationToken cancellationToken) { - Contract.Assert(tasks != null, "Expected a non-null list of tasks"); - Contract.Assert(tasks.Count > 0, "Expected at least one task"); + Debug.Assert(tasks != null, "Expected a non-null list of tasks"); + Debug.Assert(tasks.Count > 0, "Expected at least one task"); bool waitCompleted = false; var mres = new SetOnCountdownMres(tasks.Count); @@ -5206,14 +5193,14 @@ namespace System.Threading.Tasks internal SetOnCountdownMres(int count) { - Contract.Assert(count > 0, "Expected count > 0"); + Debug.Assert(count > 0, "Expected count > 0"); _count = count; } public void Invoke(Task completingTask) { if (Interlocked.Decrement(ref _count) == 0) Set(); - Contract.Assert(_count >= 0, "Count should never go below 0"); + Debug.Assert(_count >= 0, "Count should never go below 0"); } public bool InvokeMayRunArbitraryCode { get { return false; } } @@ -5304,7 +5291,7 @@ namespace System.Threading.Tasks public static int WaitAny(params Task[] tasks) { int waitResult = WaitAny(tasks, Timeout.Infinite); - Contract.Assert(tasks.Length == 0 || waitResult != -1, "expected wait to succeed"); + Debug.Assert(tasks.Length == 0 || waitResult != -1, "expected wait to succeed"); return waitResult; } @@ -5475,9 +5462,9 @@ namespace System.Threading.Tasks bool waitCompleted = firstCompleted.Wait(millisecondsTimeout, cancellationToken); if (waitCompleted) { - Contract.Assert(firstCompleted.Status == TaskStatus.RanToCompletion); + Debug.Assert(firstCompleted.Status == TaskStatus.RanToCompletion); signaledTaskIndex = Array.IndexOf(tasks, firstCompleted.Result); - Contract.Assert(signaledTaskIndex >= 0); + Debug.Assert(signaledTaskIndex >= 0); } } @@ -5521,7 +5508,7 @@ namespace System.Threading.Tasks var task = new Task<TResult>(); bool succeeded = task.TrySetException(exception); - Contract.Assert(succeeded, "This should always succeed on a new task."); + Debug.Assert(succeeded, "This should always succeed on a new task."); return task; } @@ -5559,7 +5546,7 @@ namespace System.Threading.Tasks var task = new Task<TResult>(); bool succeeded = task.TrySetCanceled(exception.CancellationToken, exception); - Contract.Assert(succeeded, "This should always succeed on a new task."); + Debug.Assert(succeeded, "This should always succeed on a new task."); return task; } @@ -6124,7 +6111,7 @@ namespace System.Threading.Tasks for (int i = 0; i < m_tasks.Length; i++) { var task = m_tasks[i]; - Contract.Assert(task != null, "Constituent task in WhenAll should never be null"); + Debug.Assert(task != null, "Constituent task in WhenAll should never be null"); if (task.IsFaulted) { @@ -6144,7 +6131,7 @@ namespace System.Threading.Tasks if (observedExceptions != null) { - Contract.Assert(observedExceptions.Count > 0, "Expected at least one exception"); + Debug.Assert(observedExceptions.Count > 0, "Expected at least one exception"); //We don't need to TraceOperationCompleted here because TrySetException will call Finish and we'll log it there @@ -6166,7 +6153,7 @@ namespace System.Threading.Tasks TrySetResult(default(VoidTaskResult)); } } - Contract.Assert(m_count >= 0, "Count should never go below 0"); + Debug.Assert(m_count >= 0, "Count should never go below 0"); } public bool InvokeMayRunArbitraryCode { get { return true; } } @@ -6371,7 +6358,7 @@ namespace System.Threading.Tasks for (int i = 0; i < m_tasks.Length; i++) { Task<T> task = m_tasks[i]; - Contract.Assert(task != null, "Constituent task in WhenAll should never be null"); + Debug.Assert(task != null, "Constituent task in WhenAll should never be null"); if (task.IsFaulted) { @@ -6384,7 +6371,7 @@ namespace System.Threading.Tasks } else { - Contract.Assert(task.Status == TaskStatus.RanToCompletion); + Debug.Assert(task.Status == TaskStatus.RanToCompletion); results[i] = task.GetResultCore(waitCompletionNotification: false); // avoid Result, which would triggering debug notification } @@ -6396,7 +6383,7 @@ namespace System.Threading.Tasks if (observedExceptions != null) { - Contract.Assert(observedExceptions.Count > 0, "Expected at least one exception"); + Debug.Assert(observedExceptions.Count > 0, "Expected at least one exception"); //We don't need to TraceOperationCompleted here because TrySetException will call Finish and we'll log it there @@ -6418,7 +6405,7 @@ namespace System.Threading.Tasks TrySetResult(results); } } - Contract.Assert(m_count >= 0, "Count should never go below 0"); + Debug.Assert(m_count >= 0, "Count should never go below 0"); } public bool InvokeMayRunArbitraryCode { get { return true; } } @@ -6612,7 +6599,7 @@ namespace System.Threading.Tasks Task continuationTask = continuationObject as Task; if (continuationTask != null) { - Contract.Assert(continuationTask.m_action == null); + Debug.Assert(continuationTask.m_action == null); Delegate[] delegates = continuationTask.GetDelegateContinuationsForDebugger(); if (delegates != null) return delegates; @@ -6677,13 +6664,11 @@ namespace System.Threading.Tasks m_completingTask = completingTask; } - [SecurityCritical] void IThreadPoolWorkItem.ExecuteWorkItem() { m_action.Invoke(m_completingTask); } - [SecurityCritical] void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { /* NOP */ @@ -6999,25 +6984,12 @@ namespace System.Threading.Tasks // that can SO in 20 inlines on a typical 1MB stack size probably needs to be revisited anyway. private const int MAX_UNCHECKED_INLINING_DEPTH = 20; -#if !FEATURE_CORECLR - - private UInt64 m_lastKnownWatermark; - private static int s_pageSize; - - // We are conservative here. We assume that the platform needs a whole 64KB to - // respond to stack overflow. This means that for very small stacks (e.g. 128KB) - // we'll fail a lot of stack checks incorrectly. - private const long STACK_RESERVED_SPACE = 4096 * 16; - -#endif // !FEATURE_CORECLR - /// <summary> /// This method needs to be called before attempting inline execution on the current thread. /// If false is returned, it means we are too close to the end of the stack and should give up inlining. /// Each call to TryBeginInliningScope() that returns true must be matched with a /// call to EndInliningScope() regardless of whether inlining actually took place. /// </summary> - [SecuritySafeCritical] internal bool TryBeginInliningScope() { // If we're still under the 'safe' limit we'll just skip the stack probe to save p/invoke calls @@ -7037,59 +7009,15 @@ namespace System.Threading.Tasks internal void EndInliningScope() { m_inliningDepth--; - Contract.Assert(m_inliningDepth >= 0, "Inlining depth count should never go negative."); + Debug.Assert(m_inliningDepth >= 0, "Inlining depth count should never go negative."); // do the right thing just in case... if (m_inliningDepth < 0) m_inliningDepth = 0; } - [SecurityCritical] private unsafe bool CheckForSufficientStack() { -#if FEATURE_CORECLR return RuntimeHelpers.TryEnsureSufficientExecutionStack(); -#else - // see if we already have the system page size info recorded - int pageSize = s_pageSize; - if (pageSize == 0) - { - // If not we need to query it from GetSystemInfo() - // Note that this happens only once for the process lifetime - Win32Native.SYSTEM_INFO sysInfo = new Win32Native.SYSTEM_INFO(); - Win32Native.GetSystemInfo(ref sysInfo); - - s_pageSize = pageSize = sysInfo.dwPageSize; - } - - Win32Native.MEMORY_BASIC_INFORMATION stackInfo = new Win32Native.MEMORY_BASIC_INFORMATION(); - - // We subtract one page for our request. VirtualQuery rounds UP to the next page. - // Unfortunately, the stack grows down. If we're on the first page (last page in the - // VirtualAlloc), we'll be moved to the next page, which is off the stack! - - UIntPtr currentAddr = new UIntPtr(&stackInfo - pageSize); - UInt64 current64 = currentAddr.ToUInt64(); - - // Check whether we previously recorded a deeper stack than where we currently are, - // If so we don't need to do the P/Invoke to VirtualQuery - if (m_lastKnownWatermark != 0 && current64 > m_lastKnownWatermark) - return true; - - // Actual stack probe. P/Invoke to query for the current stack allocation information. - Win32Native.VirtualQuery(currentAddr.ToPointer(), ref stackInfo, (UIntPtr)(sizeof(Win32Native.MEMORY_BASIC_INFORMATION))); - - // If the current address minus the base (remember: the stack grows downward in the - // address space) is greater than the number of bytes requested plus the reserved - // space at the end, the request has succeeded. - - if ((current64 - ((UIntPtr)stackInfo.AllocationBase).ToUInt64()) > STACK_RESERVED_SPACE) - { - m_lastKnownWatermark = current64; - return true; - } - - return false; -#endif } } @@ -7204,16 +7132,15 @@ namespace System.Threading.Tasks case STATE_WAITING_ON_INNER_TASK: bool result = TrySetFromTask(completingTask, lookForOce: false); _state = STATE_DONE; // bump the state - Contract.Assert(result, "Expected TrySetFromTask from inner task to succeed"); + Debug.Assert(result, "Expected TrySetFromTask from inner task to succeed"); break; default: - Contract.Assert(false, "UnwrapPromise in illegal state"); + Debug.Assert(false, "UnwrapPromise in illegal state"); break; } } // Calls InvokeCore asynchronously. - [SecuritySafeCritical] private void InvokeCoreAsync(Task completingTask) { // Queue a call to Invoke. If we're so deep on the stack that we're at risk of overflowing, @@ -7233,7 +7160,7 @@ namespace System.Threading.Tasks private void ProcessCompletedOuterTask(Task task) { Contract.Requires(task != null && task.IsCompleted, "Expected non-null, completed outer task"); - Contract.Assert(_state == STATE_WAITING_ON_OUTER_TASK, "We're in the wrong state!"); + Debug.Assert(_state == STATE_WAITING_ON_OUTER_TASK, "We're in the wrong state!"); // Bump our state before proceeding any further _state = STATE_WAITING_ON_INNER_TASK; @@ -7245,7 +7172,7 @@ namespace System.Threading.Tasks case TaskStatus.Canceled: case TaskStatus.Faulted: bool result = TrySetFromTask(task, _lookForOce); - Contract.Assert(result, "Expected TrySetFromTask from outer task to succeed"); + Debug.Assert(result, "Expected TrySetFromTask from outer task to succeed"); break; // Otherwise, process the inner task it returned. diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs b/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs index 8b1dd2a62f..320f704f09 100644 --- a/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs +++ b/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs @@ -12,6 +12,7 @@ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -47,7 +48,6 @@ namespace System.Threading.Tasks /// </remarks> /// <typeparam name="TResult">The type of the result value assocatied with this <see /// cref="TaskCompletionSource{TResult}"/>.</typeparam> - [HostProtection(Synchronization = true, ExternalThreading = true)] public class TaskCompletionSource<TResult> { private readonly Task<TResult> m_task; @@ -209,9 +209,9 @@ namespace System.Threading.Tasks /// <remarks>Unlike the public methods, this method doesn't currently validate that its arguments are correct.</remarks> internal bool TrySetException(IEnumerable<ExceptionDispatchInfo> exceptions) { - Contract.Assert(exceptions != null); + Debug.Assert(exceptions != null); #if DEBUG - foreach(var edi in exceptions) Contract.Assert(edi != null, "Contents must be non-null"); + foreach(var edi in exceptions) Debug.Assert(edi != null, "Contents must be non-null"); #endif bool rval = m_task.TrySetException(exceptions); diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs b/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs index 4c035dfddb..70b9418dbf 100644 --- a/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs +++ b/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs @@ -11,6 +11,7 @@ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System.Security; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.ExceptionServices; using System.Runtime.CompilerServices; @@ -45,7 +46,7 @@ namespace System.Threading.Tasks // Get and null out the antecedent. This is crucial to avoid a memory // leak with long chains of continuations. var antecedent = m_antecedent; - Contract.Assert(antecedent != null, + Debug.Assert(antecedent != null, "No antecedent was set for the ContinuationTaskFromTask."); m_antecedent = null; @@ -53,7 +54,7 @@ namespace System.Threading.Tasks antecedent.NotifyDebuggerOfWaitCompletionIfNecessary(); // Invoke the delegate - Contract.Assert(m_action != null); + Debug.Assert(m_action != null); var action = m_action as Action<Task>; if (action != null) { @@ -66,7 +67,7 @@ namespace System.Threading.Tasks actionWithState(antecedent, m_stateObject); return; } - Contract.Assert(false, "Invalid m_action in ContinuationTaskFromTask"); + Debug.Assert(false, "Invalid m_action in ContinuationTaskFromTask"); } } @@ -93,7 +94,7 @@ namespace System.Threading.Tasks // Get and null out the antecedent. This is crucial to avoid a memory // leak with long chains of continuations. var antecedent = m_antecedent; - Contract.Assert(antecedent != null, + Debug.Assert(antecedent != null, "No antecedent was set for the ContinuationResultTaskFromTask."); m_antecedent = null; @@ -101,7 +102,7 @@ namespace System.Threading.Tasks antecedent.NotifyDebuggerOfWaitCompletionIfNecessary(); // Invoke the delegate - Contract.Assert(m_action != null); + Debug.Assert(m_action != null); var func = m_action as Func<Task, TResult>; if (func != null) { @@ -114,7 +115,7 @@ namespace System.Threading.Tasks m_result = funcWithState(antecedent, m_stateObject); return; } - Contract.Assert(false, "Invalid m_action in ContinuationResultTaskFromTask"); + Debug.Assert(false, "Invalid m_action in ContinuationResultTaskFromTask"); } } @@ -141,7 +142,7 @@ namespace System.Threading.Tasks // Get and null out the antecedent. This is crucial to avoid a memory // leak with long chains of continuations. var antecedent = m_antecedent; - Contract.Assert(antecedent != null, + Debug.Assert(antecedent != null, "No antecedent was set for the ContinuationTaskFromResultTask."); m_antecedent = null; @@ -149,7 +150,7 @@ namespace System.Threading.Tasks antecedent.NotifyDebuggerOfWaitCompletionIfNecessary(); // Invoke the delegate - Contract.Assert(m_action != null); + Debug.Assert(m_action != null); var action = m_action as Action<Task<TAntecedentResult>>; if (action != null) { @@ -162,7 +163,7 @@ namespace System.Threading.Tasks actionWithState(antecedent, m_stateObject); return; } - Contract.Assert(false, "Invalid m_action in ContinuationTaskFromResultTask"); + Debug.Assert(false, "Invalid m_action in ContinuationTaskFromResultTask"); } } @@ -189,7 +190,7 @@ namespace System.Threading.Tasks // Get and null out the antecedent. This is crucial to avoid a memory // leak with long chains of continuations. var antecedent = m_antecedent; - Contract.Assert(antecedent != null, + Debug.Assert(antecedent != null, "No antecedent was set for the ContinuationResultTaskFromResultTask."); m_antecedent = null; @@ -197,7 +198,7 @@ namespace System.Threading.Tasks antecedent.NotifyDebuggerOfWaitCompletionIfNecessary(); // Invoke the delegate - Contract.Assert(m_action != null); + Debug.Assert(m_action != null); var func = m_action as Func<Task<TAntecedentResult>, TResult>; if (func != null) { @@ -210,7 +211,7 @@ namespace System.Threading.Tasks m_result = funcWithState(antecedent, m_stateObject); return; } - Contract.Assert(false, "Invalid m_action in ContinuationResultTaskFromResultTask"); + Debug.Assert(false, "Invalid m_action in ContinuationResultTaskFromResultTask"); } } @@ -235,11 +236,10 @@ namespace System.Threading.Tasks /// <param name="needsProtection"> /// true if we need to protect against multiple threads racing to start/cancel the task; otherwise, false. /// </param> - [SecuritySafeCritical] protected static void InlineIfPossibleOrElseQueue(Task task, bool needsProtection) { Contract.Requires(task != null); - Contract.Assert(task.m_taskScheduler != null); + Debug.Assert(task.m_taskScheduler != null); // Set the TASK_STATE_STARTED flag. This only needs to be done // if the task may be canceled or if someone else has a reference to it @@ -305,7 +305,7 @@ namespace System.Threading.Tasks m_options = options; m_taskScheduler = scheduler; if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, m_task.Id, "Task.ContinueWith: " + ((Delegate)task.m_action).Method.Name, 0); + AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, m_task.Id, "Task.ContinueWith: " + task.m_action.Method.Name, 0); if (Task.s_asyncDebuggingEnabled) { @@ -318,8 +318,8 @@ namespace System.Threading.Tasks /// <param name="bCanInlineContinuationTask">Whether the continuation can be inlined.</param> internal override void Run(Task completedTask, bool bCanInlineContinuationTask) { - Contract.Assert(completedTask != null); - Contract.Assert(completedTask.IsCompleted, "ContinuationTask.Run(): completedTask not completed"); + Debug.Assert(completedTask != null); + Debug.Assert(completedTask.IsCompleted, "ContinuationTask.Run(): completedTask not completed"); // Check if the completion status of the task works with the desired // activation criteria of the TaskContinuationOptions. @@ -374,7 +374,7 @@ namespace System.Threading.Tasks return m_task.GetDelegateContinuationsForDebugger(); } - return new Delegate[] { m_task.m_action as Delegate }; + return new Delegate[] { m_task.m_action }; } } @@ -384,7 +384,6 @@ namespace System.Threading.Tasks /// <summary>SendOrPostCallback delegate to invoke the action.</summary> private readonly static SendOrPostCallback s_postCallback = state => ((Action)state)(); // can't use InvokeAction as it's SecurityCritical /// <summary>Cached delegate for PostAction</summary> - [SecurityCritical] private static ContextCallback s_postActionCallback; /// <summary>The context with which to run the action.</summary> private readonly SynchronizationContext m_syncContext; @@ -394,19 +393,17 @@ namespace System.Threading.Tasks /// <param name="action">The action to invoke. Must not be null.</param> /// <param name="flowExecutionContext">Whether to capture and restore ExecutionContext.</param> /// <param name="stackMark">The captured stack mark.</param> - [SecurityCritical] internal SynchronizationContextAwaitTaskContinuation( SynchronizationContext context, Action action, bool flowExecutionContext, ref StackCrawlMark stackMark) : base(action, flowExecutionContext, ref stackMark) { - Contract.Assert(context != null); + Debug.Assert(context != null); m_syncContext = context; } /// <summary>Inlines or schedules the continuation.</summary> /// <param name="ignored">The antecedent task, which is ignored.</param> /// <param name="canInlineContinuationTask">true if inlining is permitted; otherwise, false.</param> - [SecuritySafeCritical] internal sealed override void Run(Task task, bool canInlineContinuationTask) { // If we're allowed to inline, run the action on this thread. @@ -431,7 +428,6 @@ namespace System.Threading.Tasks /// <summary>Calls InvokeOrPostAction(false) on the supplied SynchronizationContextAwaitTaskContinuation.</summary> /// <param name="state">The SynchronizationContextAwaitTaskContinuation.</param> - [SecurityCritical] private static void PostAction(object state) { var c = (SynchronizationContextAwaitTaskContinuation)state; @@ -465,7 +461,6 @@ namespace System.Threading.Tasks /// to be passed as state. /// </returns> [MethodImpl(MethodImplOptions.AggressiveInlining)] - [SecurityCritical] private static ContextCallback GetPostActionCallback() { ContextCallback callback = s_postActionCallback; @@ -485,12 +480,11 @@ namespace System.Threading.Tasks /// <param name="action">The action to invoke. Must not be null.</param> /// <param name="flowExecutionContext">Whether to capture and restore ExecutionContext.</param> /// <param name="stackMark">The captured stack mark.</param> - [SecurityCritical] internal TaskSchedulerAwaitTaskContinuation( TaskScheduler scheduler, Action action, bool flowExecutionContext, ref StackCrawlMark stackMark) : base(action, flowExecutionContext, ref stackMark) { - Contract.Assert(scheduler != null); + Debug.Assert(scheduler != null); m_scheduler = scheduler; } @@ -550,7 +544,6 @@ namespace System.Threading.Tasks /// <param name="action">The action to invoke. Must not be null.</param> /// <param name="flowExecutionContext">Whether to capture and restore ExecutionContext.</param> /// <param name="stackMark">The captured stack mark with which to construct an ExecutionContext.</param> - [SecurityCritical] internal AwaitTaskContinuation(Action action, bool flowExecutionContext, ref StackCrawlMark stackMark) { Contract.Requires(action != null); @@ -566,7 +559,6 @@ namespace System.Threading.Tasks /// <summary>Initializes the continuation.</summary> /// <param name="action">The action to invoke. Must not be null.</param> /// <param name="flowExecutionContext">Whether to capture and restore ExecutionContext.</param> - [SecurityCritical] internal AwaitTaskContinuation(Action action, bool flowExecutionContext) { Contract.Requires(action != null); @@ -598,7 +590,6 @@ namespace System.Threading.Tasks /// <summary>Inlines or schedules the continuation onto the default scheduler.</summary> /// <param name="ignored">The antecedent task, which is ignored.</param> /// <param name="canInlineContinuationTask">true if inlining is permitted; otherwise, false.</param> - [SecuritySafeCritical] internal override void Run(Task task, bool canInlineContinuationTask) { // For the base AwaitTaskContinuation, we allow inlining if our caller allows it @@ -657,7 +648,6 @@ namespace System.Threading.Tasks } /// <summary>IThreadPoolWorkItem override, which is the entry function for this when the ThreadPool scheduler decides to run it.</summary> - [SecurityCritical] void ExecuteWorkItemHelper() { var etwLog = TplEtwProvider.Log; @@ -696,7 +686,6 @@ namespace System.Threading.Tasks } } - [SecurityCritical] void IThreadPoolWorkItem.ExecuteWorkItem() { // inline the fast path @@ -714,20 +703,16 @@ namespace System.Threading.Tasks /// <summary> /// The ThreadPool calls this if a ThreadAbortException is thrown while trying to execute this workitem. /// </summary> - [SecurityCritical] void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { /* nop */ } /// <summary>Cached delegate that invokes an Action passed as an object parameter.</summary> - [SecurityCritical] private static ContextCallback s_invokeActionCallback; /// <summary>Runs an action provided as an object parameter.</summary> /// <param name="state">The Action to invoke.</param> - [SecurityCritical] private static void InvokeAction(object state) { ((Action)state)(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - [SecurityCritical] protected static ContextCallback GetInvokeActionCallback() { ContextCallback callback = s_invokeActionCallback; @@ -739,11 +724,10 @@ namespace System.Threading.Tasks /// <param name="callback">The callback to run.</param> /// <param name="state">The state to pass to the callback.</param> /// <param name="currentTask">A reference to Task.t_currentTask.</param> - [SecurityCritical] protected void RunCallback(ContextCallback callback, object state, ref Task currentTask) { Contract.Requires(callback != null); - Contract.Assert(currentTask == Task.t_currentTask); + Debug.Assert(currentTask == Task.t_currentTask); // Pretend there's no current task, so that no task is seen as a parent // and TaskScheduler.Current does not reflect false information @@ -787,10 +771,9 @@ namespace System.Threading.Tasks /// only happens in Task.SetContinuationForAwait if execution context flow was disabled /// via using TaskAwaiter.UnsafeOnCompleted or a similar path. /// </remarks> - [SecurityCritical] internal static void RunOrScheduleAction(Action action, bool allowInlining, ref Task currentTask) { - Contract.Assert(currentTask == Task.t_currentTask); + Debug.Assert(currentTask == Task.t_currentTask); // If we're not allowed to run here, schedule the action if (!allowInlining || !IsValidLocationForInlining) @@ -818,7 +801,6 @@ namespace System.Threading.Tasks /// <summary>Schedules the action to be executed. No ExecutionContext work is performed used.</summary> /// <param name="action">The action to invoke or queue.</param> - [SecurityCritical] internal static void UnsafeScheduleAction(Action action, Task task) { AwaitTaskContinuation atc = new AwaitTaskContinuation(action, flowExecutionContext: false); @@ -859,7 +841,7 @@ namespace System.Threading.Tasks internal override Delegate[] GetDelegateContinuationsForDebugger() { - Contract.Assert(m_action != null); + Debug.Assert(m_action != null); return new Delegate[] { AsyncMethodBuilderCore.TryGetStateMachineForDebugger(m_action) }; } } diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs b/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs index 198db8e15c..45817dab23 100644 --- a/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs +++ b/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs @@ -18,6 +18,7 @@ namespace System.Threading.Tasks using System; using System.Collections.Generic; using System.Collections.ObjectModel; + using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.ExceptionServices; using System.Security; @@ -62,14 +63,9 @@ namespace System.Threading.Tasks EnsureADUnloadCallbackRegistered(); } - [SecuritySafeCritical] private static bool ShouldFailFastOnUnobservedException() { - bool shouldFailFast = false; - #if !FEATURE_CORECLR - shouldFailFast = System.CLRConfig.CheckThrowUnobservedTaskExceptions(); - #endif - return shouldFailFast; + return false; } private static void EnsureADUnloadCallbackRegistered() @@ -202,12 +198,12 @@ namespace System.Threading.Tasks { Contract.Requires(exceptionObject != null, "Expected exceptionObject to be non-null."); - Contract.Assert(m_cancellationException == null, + Debug.Assert(m_cancellationException == null, "Expected SetCancellationException to be called only once."); // Breaking this assumption will overwrite a previously OCE, // and implies something may be wrong elsewhere, since there should only ever be one. - Contract.Assert(m_faultExceptions == null, + Debug.Assert(m_faultExceptions == null, "Expected SetCancellationException to be called before any faults were added."); // Breaking this assumption shouldn't hurt anything here, but it implies something may be wrong elsewhere. // If this changes, make sure to only conditionally mark as handled below. @@ -221,7 +217,7 @@ namespace System.Threading.Tasks else { var edi = exceptionObject as ExceptionDispatchInfo; - Contract.Assert(edi != null && edi.SourceException is OperationCanceledException, + Debug.Assert(edi != null && edi.SourceException is OperationCanceledException, "Expected an OCE or an EDI that contained an OCE"); m_cancellationException = edi; } @@ -242,7 +238,7 @@ namespace System.Threading.Tasks // Initialize the exceptions list if necessary. The list should be non-null iff it contains exceptions. var exceptions = m_faultExceptions; if (exceptions == null) m_faultExceptions = exceptions = new List<ExceptionDispatchInfo>(1); - else Contract.Assert(exceptions.Count > 0, "Expected existing exceptions list to have > 0 exceptions."); + else Debug.Assert(exceptions.Count > 0, "Expected existing exceptions list to have > 0 exceptions."); // Handle Exception by capturing it into an ExceptionDispatchInfo and storing that var exception = exceptionObject as Exception; @@ -270,13 +266,13 @@ namespace System.Threading.Tasks foreach (var exc in exColl) { #if DEBUG - Contract.Assert(exc != null, "No exceptions should be null"); + Debug.Assert(exc != null, "No exceptions should be null"); numExceptions++; #endif exceptions.Add(ExceptionDispatchInfo.Capture(exc)); } #if DEBUG - Contract.Assert(numExceptions > 0, "Collection should contain at least one exception."); + Debug.Assert(numExceptions > 0, "Collection should contain at least one exception."); #endif } else @@ -287,17 +283,17 @@ namespace System.Threading.Tasks { exceptions.AddRange(ediColl); #if DEBUG - Contract.Assert(exceptions.Count > 0, "There should be at least one dispatch info."); + Debug.Assert(exceptions.Count > 0, "There should be at least one dispatch info."); foreach(var tmp in exceptions) { - Contract.Assert(tmp != null, "No dispatch infos should be null"); + Debug.Assert(tmp != null, "No dispatch infos should be null"); } #endif } // Anything else is a programming error else { - throw new ArgumentException(Environment.GetResourceString("TaskExceptionHolder_UnknownExceptionType"), "exceptionObject"); + throw new ArgumentException(Environment.GetResourceString("TaskExceptionHolder_UnknownExceptionType"), nameof(exceptionObject)); } } } @@ -370,8 +366,8 @@ namespace System.Threading.Tasks internal AggregateException CreateExceptionObject(bool calledFromFinalizer, Exception includeThisException) { var exceptions = m_faultExceptions; - Contract.Assert(exceptions != null, "Expected an initialized list."); - Contract.Assert(exceptions.Count > 0, "Expected at least one exception."); + Debug.Assert(exceptions != null, "Expected an initialized list."); + Debug.Assert(exceptions.Count > 0, "Expected at least one exception."); // Mark as handled and aggregate the exceptions. MarkAsHandled(calledFromFinalizer); @@ -400,8 +396,8 @@ namespace System.Threading.Tasks internal ReadOnlyCollection<ExceptionDispatchInfo> GetExceptionDispatchInfos() { var exceptions = m_faultExceptions; - Contract.Assert(exceptions != null, "Expected an initialized list."); - Contract.Assert(exceptions.Count > 0, "Expected at least one exception."); + Debug.Assert(exceptions != null, "Expected an initialized list."); + Debug.Assert(exceptions.Count > 0, "Expected at least one exception."); MarkAsHandled(false); return new ReadOnlyCollection<ExceptionDispatchInfo>(exceptions); } @@ -416,7 +412,7 @@ namespace System.Threading.Tasks internal ExceptionDispatchInfo GetCancellationExceptionDispatchInfo() { var edi = m_cancellationException; - Contract.Assert(edi == null || edi.SourceException is OperationCanceledException, + Debug.Assert(edi == null || edi.SourceException is OperationCanceledException, "Expected the EDI to be for an OperationCanceledException"); return edi; } diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs b/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs index 52b471628a..aa4c2df74b 100644 --- a/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs +++ b/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs @@ -18,6 +18,7 @@ using System.Security; using System.Security.Permissions; using System.Runtime.CompilerServices; using System.Threading; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace System.Threading.Tasks @@ -37,7 +38,6 @@ namespace System.Threading.Tasks /// <see cref="System.Threading.Tasks.Task.Factory">Task.Factory</see> property. /// </para> /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public class TaskFactory { // member variables @@ -225,7 +225,7 @@ namespace System.Threading.Tasks TaskCreationOptions.PreferFairness | TaskCreationOptions.RunContinuationsAsynchronously)) != 0) { - throw new ArgumentOutOfRangeException("creationOptions"); + throw new ArgumentOutOfRangeException(nameof(creationOptions)); } Contract.EndContractBlock(); } @@ -1593,9 +1593,9 @@ namespace System.Threading.Tasks { // Options detected here cause exceptions in FromAsync methods that take beginMethod as a parameter if ((creationOptions & TaskCreationOptions.LongRunning) != 0) - throw new ArgumentOutOfRangeException("creationOptions", Environment.GetResourceString("Task_FromAsync_LongRunning")); + throw new ArgumentOutOfRangeException(nameof(creationOptions), Environment.GetResourceString("Task_FromAsync_LongRunning")); if ((creationOptions & TaskCreationOptions.PreferFairness) != 0) - throw new ArgumentOutOfRangeException("creationOptions", Environment.GetResourceString("Task_FromAsync_PreferFairness")); + throw new ArgumentOutOfRangeException(nameof(creationOptions), Environment.GetResourceString("Task_FromAsync_PreferFairness")); } // Check for general validity of options @@ -1606,7 +1606,7 @@ namespace System.Threading.Tasks TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning)) != 0) { - throw new ArgumentOutOfRangeException("creationOptions"); + throw new ArgumentOutOfRangeException(nameof(creationOptions)); } } @@ -1666,7 +1666,7 @@ namespace System.Threading.Tasks TrySetResult(_tasks); } - Contract.Assert(_count >= 0, "Count should never go below 0"); + Debug.Assert(_count >= 0, "Count should never go below 0"); } public bool InvokeMayRunArbitraryCode { get { return true; } } @@ -1746,7 +1746,7 @@ namespace System.Threading.Tasks TrySetResult(_tasks); } - Contract.Assert(_count >= 0, "Count should never go below 0"); + Debug.Assert(_count >= 0, "Count should never go below 0"); } public bool InvokeMayRunArbitraryCode { get { return true; } } @@ -1801,7 +1801,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -1833,7 +1833,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -1870,7 +1870,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, TaskContinuationOptions continuationOptions) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -1918,7 +1918,7 @@ namespace System.Threading.Tasks public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -1945,7 +1945,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -1979,7 +1979,7 @@ namespace System.Threading.Tasks public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction, CancellationToken cancellationToken) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2018,7 +2018,7 @@ namespace System.Threading.Tasks public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction, TaskContinuationOptions continuationOptions) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2067,7 +2067,7 @@ namespace System.Threading.Tasks public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2097,7 +2097,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2133,7 +2133,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, CancellationToken cancellationToken) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2174,7 +2174,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, TaskContinuationOptions continuationOptions) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2226,7 +2226,7 @@ namespace System.Threading.Tasks public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2258,7 +2258,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2295,7 +2295,7 @@ namespace System.Threading.Tasks public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction, CancellationToken cancellationToken) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2338,7 +2338,7 @@ namespace System.Threading.Tasks public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction, TaskContinuationOptions continuationOptions) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2391,7 +2391,7 @@ namespace System.Threading.Tasks public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2448,7 +2448,7 @@ namespace System.Threading.Tasks } bool success = TrySetResult(completingTask); - Contract.Assert(success, "Only one task should have gotten to this point, and thus this must be successful."); + Debug.Assert(success, "Only one task should have gotten to this point, and thus this must be successful."); // We need to remove continuations that may be left straggling on other tasks. // Otherwise, repeated calls to WhenAny using the same task could leak actions. @@ -2489,7 +2489,7 @@ namespace System.Threading.Tasks for(int i=0; i<numTasks; i++) { var task = tasks[i]; - if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks"); + if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks)); if (checkArgsOnly) continue; @@ -2531,7 +2531,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2562,7 +2562,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2599,7 +2599,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, TaskContinuationOptions continuationOptions) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2647,7 +2647,7 @@ namespace System.Threading.Tasks public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2678,7 +2678,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2713,7 +2713,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, CancellationToken cancellationToken) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2754,7 +2754,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, TaskContinuationOptions continuationOptions) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2806,7 +2806,7 @@ namespace System.Threading.Tasks public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2838,7 +2838,7 @@ namespace System.Threading.Tasks public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark); } @@ -2872,7 +2872,7 @@ namespace System.Threading.Tasks public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction, CancellationToken cancellationToken) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2915,7 +2915,7 @@ namespace System.Threading.Tasks public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction, TaskContinuationOptions continuationOptions) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2968,7 +2968,7 @@ namespace System.Threading.Tasks public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { - if (continuationFunction == null) throw new ArgumentNullException("continuationFunction"); + if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -2996,7 +2996,7 @@ namespace System.Threading.Tasks [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -3029,7 +3029,7 @@ namespace System.Threading.Tasks public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction, CancellationToken cancellationToken) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -3068,7 +3068,7 @@ namespace System.Threading.Tasks public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction, TaskContinuationOptions continuationOptions) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -3117,7 +3117,7 @@ namespace System.Threading.Tasks public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { - if (continuationAction == null) throw new ArgumentNullException("continuationAction"); + if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction)); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -3129,9 +3129,9 @@ namespace System.Threading.Tasks internal static Task[] CheckMultiContinuationTasksAndCopy(Task[] tasks) { if (tasks == null) - throw new ArgumentNullException("tasks"); + throw new ArgumentNullException(nameof(tasks)); if (tasks.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks"); + throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), nameof(tasks)); Contract.EndContractBlock(); Task[] tasksCopy = new Task[tasks.Length]; @@ -3140,7 +3140,7 @@ namespace System.Threading.Tasks tasksCopy[i] = tasks[i]; if (tasksCopy[i] == null) - throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks"); + throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks)); } return tasksCopy; @@ -3149,9 +3149,9 @@ namespace System.Threading.Tasks internal static Task<TResult>[] CheckMultiContinuationTasksAndCopy<TResult>(Task<TResult>[] tasks) { if (tasks == null) - throw new ArgumentNullException("tasks"); + throw new ArgumentNullException(nameof(tasks)); if (tasks.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks"); + throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), nameof(tasks)); Contract.EndContractBlock(); Task<TResult>[] tasksCopy = new Task<TResult>[tasks.Length]; @@ -3160,7 +3160,7 @@ namespace System.Threading.Tasks tasksCopy[i] = tasks[i]; if (tasksCopy[i] == null) - throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks"); + throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks)); } return tasksCopy; @@ -3179,7 +3179,7 @@ namespace System.Threading.Tasks const TaskContinuationOptions illegalMask = TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.LongRunning; if ((continuationOptions & illegalMask) == illegalMask) { - throw new ArgumentOutOfRangeException("continuationOptions", Environment.GetResourceString("Task_ContinueWith_ESandLR")); + throw new ArgumentOutOfRangeException(nameof(continuationOptions), Environment.GetResourceString("Task_ContinueWith_ESandLR")); } // Check that no nonsensical options are specified. @@ -3193,12 +3193,12 @@ namespace System.Threading.Tasks NotOnAny | TaskContinuationOptions.ExecuteSynchronously)) != 0) { - throw new ArgumentOutOfRangeException("continuationOptions"); + throw new ArgumentOutOfRangeException(nameof(continuationOptions)); } // Check that no "fire" options are specified. if ((continuationOptions & NotOnAny) != 0) - throw new ArgumentOutOfRangeException("continuationOptions", Environment.GetResourceString("Task_MultiTaskContinuation_FireOptions")); + throw new ArgumentOutOfRangeException(nameof(continuationOptions), Environment.GetResourceString("Task_MultiTaskContinuation_FireOptions")); Contract.EndContractBlock(); } } diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs b/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs index f82492499c..fad3fc06c5 100644 --- a/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs +++ b/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs @@ -41,10 +41,6 @@ namespace System.Threading.Tasks /// </remarks> [DebuggerDisplay("Id={Id}")] [DebuggerTypeProxy(typeof(SystemThreadingTasks_TaskSchedulerDebugView))] - [HostProtection(Synchronization = true, ExternalThreading = true)] -#pragma warning disable 618 - [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)] -#pragma warning restore 618 public abstract class TaskScheduler { //////////////////////////////////////////////////////////// @@ -70,7 +66,6 @@ namespace System.Threading.Tasks /// </remarks> /// <param name="task">The <see cref="T:System.Threading.Tasks.Task">Task</see> to be queued.</param> /// <exception cref="T:System.ArgumentNullException">The <paramref name="task"/> argument is null.</exception> - [SecurityCritical] protected internal abstract void QueueTask(Task task); /// <summary> @@ -113,7 +108,6 @@ namespace System.Threading.Tasks /// null.</exception> /// <exception cref="T:System.InvalidOperationException">The <paramref name="task"/> was already /// executed.</exception> - [SecurityCritical] protected abstract bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued); /// <summary> @@ -157,7 +151,6 @@ namespace System.Threading.Tasks /// <exception cref="T:System.NotSupportedException"> /// This scheduler is unable to generate a list of queued tasks at this time. /// </exception> - [SecurityCritical] protected abstract IEnumerable<Task> GetScheduledTasks(); /// <summary> @@ -185,7 +178,6 @@ namespace System.Threading.Tasks /// <param name="taskWasPreviouslyQueued">True if the task may have been previously queued, /// false if the task was absolutely not previously queued.</param> /// <returns>True if it ran, false otherwise.</returns> - [SecuritySafeCritical] internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued) { // Do not inline unstarted tasks (i.e., task.ExecutingTaskScheduler == null). @@ -237,7 +229,6 @@ namespace System.Threading.Tasks /// <param name="task">The <see cref="T:System.Threading.Tasks.Task">Task</see> to be dequeued.</param> /// <returns>A Boolean denoting whether the <paramref name="task"/> argument was successfully dequeued.</returns> /// <exception cref="T:System.ArgumentNullException">The <paramref name="task"/> argument is null.</exception> - [SecurityCritical] protected internal virtual bool TryDequeue(Task task) { return false; @@ -262,7 +253,6 @@ namespace System.Threading.Tasks /// <summary> /// Calls QueueTask() after performing any needed firing of events /// </summary> - [SecurityCritical] internal void InternalQueueTask(Task task) { Contract.Requires(task != null); @@ -444,7 +434,6 @@ namespace System.Threading.Tasks /// <returns>A Boolean that is true if <paramref name="task"/> was successfully executed, false if it /// was not. A common reason for execution failure is that the task had previously been executed or /// is in the process of being executed by another thread.</returns> - [SecurityCritical] protected bool TryExecuteTask(Task task) { if (task.ExecutingTaskScheduler != this) @@ -475,7 +464,6 @@ namespace System.Threading.Tasks /// </remarks> public static event EventHandler<UnobservedTaskExceptionEventArgs> UnobservedTaskException { - [System.Security.SecurityCritical] add { if (value != null) @@ -485,7 +473,6 @@ namespace System.Threading.Tasks } } - [System.Security.SecurityCritical] remove { lock (_unobservedTaskExceptionLockObject) _unobservedTaskException -= value; @@ -531,7 +518,6 @@ namespace System.Threading.Tasks /// <exception cref="T:System.NotSupportedException"> /// This scheduler is unable to generate a list of queued tasks at this time. /// </exception> - [SecurityCritical] internal Task[] GetScheduledTasksForDebugger() { // this can throw InvalidOperationException indicating that they are unable to provide the info @@ -566,7 +552,6 @@ namespace System.Threading.Tasks /// It should not be called by any other codepaths. /// </remarks> /// <returns>An array of <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> instances.</returns> - [SecurityCritical] internal static TaskScheduler[] GetTaskSchedulersForDebugger() { if (s_activeTaskSchedulers == null) @@ -587,7 +572,7 @@ namespace System.Threading.Tasks schedulers.CopyTo(arr, 0); foreach (var scheduler in arr) { - Contract.Assert(scheduler != null, "Table returned an incorrect Count or CopyTo failed"); + Debug.Assert(scheduler != null, "Table returned an incorrect Count or CopyTo failed"); int tmp = scheduler.Id; // force Ids for debugger } return arr; @@ -613,7 +598,6 @@ namespace System.Threading.Tasks // returns the scheduler’s GetScheduledTasks public IEnumerable<Task> ScheduledTasks { - [SecurityCritical] get { return m_taskScheduler.GetScheduledTasks(); } } } @@ -656,7 +640,6 @@ namespace System.Threading.Tasks /// Simply posts the tasks to be executed on the associated <see cref="T:System.Threading.SynchronizationContext"/>. /// </summary> /// <param name="task"></param> - [SecurityCritical] protected internal override void QueueTask(Task task) { m_synchronizationContext.Post(s_postCallback, (object)task); @@ -670,7 +653,6 @@ namespace System.Threading.Tasks /// </summary> /// <param name="task"></param> /// <param name="taskWasPreviouslyQueued"></param> - [SecurityCritical] protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { if (SynchronizationContext.Current == m_synchronizationContext) @@ -682,7 +664,6 @@ namespace System.Threading.Tasks } // not implemented - [SecurityCritical] protected override IEnumerable<Task> GetScheduledTasks() { return null; diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs b/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs index 02b130c297..90743aeec5 100644 --- a/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs +++ b/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs @@ -22,6 +22,7 @@ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System.IO; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace System.Threading.Tasks @@ -76,7 +77,7 @@ namespace System.Threading.Tasks if (twar != null) { task = twar.Task; - Contract.Assert(task != null, "TaskWrapperAsyncResult should never wrap a null Task."); + Debug.Assert(task != null, "TaskWrapperAsyncResult should never wrap a null Task."); } // Otherwise, the IAsyncResult should be a Task. else @@ -101,7 +102,7 @@ namespace System.Threading.Tasks if (twar != null) { task = twar.Task as Task<TResult>; - Contract.Assert(twar.Task != null, "TaskWrapperAsyncResult should never wrap a null Task."); + Debug.Assert(twar.Task != null, "TaskWrapperAsyncResult should never wrap a null Task."); } // Otherwise, the IAsyncResult should be a Task<TResult>. else diff --git a/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs b/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs index dd4cbc9a66..5c6ca9bb76 100644 --- a/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs +++ b/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs @@ -13,6 +13,7 @@ using System; using System.Security; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Collections.Generic; using System.Text; @@ -39,7 +40,7 @@ namespace System.Threading.Tasks { Contract.Requires(obj != null, "TaskScheduler.LongRunningThreadWork: obj is null"); Task t = obj as Task; - Contract.Assert(t != null, "TaskScheduler.LongRunningThreadWork: t is null"); + Debug.Assert(t != null, "TaskScheduler.LongRunningThreadWork: t is null"); t.ExecuteEntry(false); } @@ -47,7 +48,6 @@ namespace System.Threading.Tasks /// Schedules a task to the ThreadPool. /// </summary> /// <param name="task">The task to schedule.</param> - [SecurityCritical] protected internal override void QueueTask(Task task) { if ((task.Options & TaskCreationOptions.LongRunning) != 0) @@ -73,7 +73,6 @@ namespace System.Threading.Tasks /// IMPORTANT NOTE: TryExecuteTaskInline will NOT throw task exceptions itself. Any wait code path using this function needs /// to account for exceptions that need to be propagated, and throw themselves accordingly. /// </summary> - [SecurityCritical] protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { // If the task was previously scheduled, and we can't pop it, then return false. @@ -95,14 +94,12 @@ namespace System.Threading.Tasks return rval; } - [SecurityCritical] protected internal override bool TryDequeue(Task task) { // just delegate to TP return ThreadPool.TryPopCustomWorkItem(task); } - [SecurityCritical] protected override IEnumerable<Task> GetScheduledTasks() { return FilterTasksFromWorkItems(ThreadPool.GetQueuedWorkItems()); diff --git a/src/mscorlib/src/System/Threading/Tasks/future.cs b/src/mscorlib/src/System/Threading/Tasks/future.cs index 39e6ca1d45..0c3fec89b7 100644 --- a/src/mscorlib/src/System/Threading/Tasks/future.cs +++ b/src/mscorlib/src/System/Threading/Tasks/future.cs @@ -65,7 +65,6 @@ namespace System.Threading.Tasks /// and may be used from multiple threads concurrently. /// </para> /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] [DebuggerTypeProxy(typeof(SystemThreadingTasks_FutureDebugView<>))] [DebuggerDisplay("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}, Result = {DebuggerDisplayResultDescription}")] public class Task<TResult> : Task @@ -447,7 +446,7 @@ namespace System.Threading.Tasks { get { - Delegate d = (Delegate)m_action; + Delegate d = m_action; return d != null ? d.Method.ToString() : "{null}"; } } @@ -457,7 +456,7 @@ namespace System.Threading.Tasks internal bool TrySetResult(TResult result) { if (IsCompleted) return false; - Contract.Assert(m_action == null, "Task<T>.TrySetResult(): non-null m_action"); + Debug.Assert(m_action == null, "Task<T>.TrySetResult(): non-null m_action"); // "Reserve" the completion for this task, while making sure that: (1) No prior reservation // has been made, (2) The result has not already been set, (3) An exception has not previously @@ -497,7 +496,7 @@ namespace System.Threading.Tasks // the task, avoiding expensive completion paths, before the task is actually given to anyone. internal void DangerousSetResult(TResult result) { - Contract.Assert(!IsCompleted, "The promise must not yet be completed."); + Debug.Assert(!IsCompleted, "The promise must not yet be completed."); // If we have a parent, we need to notify it of the completion. Take the slow path to handle that. if (m_contingentProperties?.m_parent != null) @@ -505,7 +504,7 @@ namespace System.Threading.Tasks bool success = TrySetResult(result); // Nobody else has had a chance to complete this Task yet, so we should succeed. - Contract.Assert(success); + Debug.Assert(success); } else { @@ -539,7 +538,7 @@ namespace System.Threading.Tasks { get { - Contract.Assert(!IsWaitNotificationEnabledOrNotRanToCompletion, + Debug.Assert(!IsWaitNotificationEnabledOrNotRanToCompletion, "Should only be used when the task completed successfully and there's no wait notification enabled"); return m_result; } @@ -558,7 +557,7 @@ namespace System.Threading.Tasks if (!IsRanToCompletion) ThrowIfExceptional(includeTaskCanceledExceptions: true); // We shouldn't be here if the result has not been set. - Contract.Assert(IsRanToCompletion, "Task<T>.Result getter: Expected result to have been set."); + Debug.Assert(IsRanToCompletion, "Task<T>.Result getter: Expected result to have been set."); return m_result; } @@ -572,13 +571,13 @@ namespace System.Threading.Tasks // Called from TaskCompletionSource<T>.SetException(IEnumerable<Exception>). internal bool TrySetException(object exceptionObject) { - Contract.Assert(m_action == null, "Task<T>.TrySetException(): non-null m_action"); + Debug.Assert(m_action == null, "Task<T>.TrySetException(): non-null m_action"); // TCS.{Try}SetException() should have checked for this - Contract.Assert(exceptionObject != null, "Expected non-null exceptionObject argument"); + Debug.Assert(exceptionObject != null, "Expected non-null exceptionObject argument"); // Only accept these types. - Contract.Assert( + Debug.Assert( (exceptionObject is Exception) || (exceptionObject is IEnumerable<Exception>) || (exceptionObject is ExceptionDispatchInfo) || (exceptionObject is IEnumerable<ExceptionDispatchInfo>), "Expected exceptionObject to be either Exception, ExceptionDispatchInfo, or IEnumerable<> of one of those"); @@ -620,10 +619,10 @@ namespace System.Threading.Tasks // This method is only valid for promise tasks. internal bool TrySetCanceled(CancellationToken tokenToRecord, object cancellationException) { - Contract.Assert(m_action == null, "Task<T>.TrySetCanceled(): non-null m_action"); + Debug.Assert(m_action == null, "Task<T>.TrySetCanceled(): non-null m_action"); #if DEBUG var ceAsEdi = cancellationException as ExceptionDispatchInfo; - Contract.Assert( + Debug.Assert( cancellationException == null || cancellationException is OperationCanceledException || (ceAsEdi != null && ceAsEdi.SourceException is OperationCanceledException), @@ -669,7 +668,7 @@ namespace System.Threading.Tasks internal override void InnerInvoke() { // Invoke the delegate - Contract.Assert(m_action != null); + Debug.Assert(m_action != null); var func = m_action as Func<TResult>; if (func != null) { @@ -682,7 +681,7 @@ namespace System.Threading.Tasks m_result = funcWithState(m_stateObject); return; } - Contract.Assert(false, "Invalid m_action in Task<TResult>"); + Debug.Assert(false, "Invalid m_action in Task<TResult>"); } #region Await Support diff --git a/src/mscorlib/src/System/Threading/Thread.cs b/src/mscorlib/src/System/Threading/Thread.cs index e62cfae9fe..8294c20c4d 100644 --- a/src/mscorlib/src/System/Threading/Thread.cs +++ b/src/mscorlib/src/System/Threading/Thread.cs @@ -12,16 +12,13 @@ ** =============================================================================*/ +using Internal.Runtime.Augments; + namespace System.Threading { using System.Threading; using System.Runtime; using System.Runtime.InteropServices; -#if FEATURE_REMOTING - using System.Runtime.Remoting.Contexts; - using System.Runtime.Remoting.Messaging; -#endif using System; - using System.Diagnostics; using System.Security.Permissions; using System.Security.Principal; using System.Globalization; @@ -31,13 +28,13 @@ namespace System.Threading { using System.Runtime.ConstrainedExecution; using System.Security; using System.Runtime.Versioning; + using System.Diagnostics; using System.Diagnostics.Contracts; internal delegate Object InternalCrossContextDelegate(Object[] args); internal class ThreadHelper { - [System.Security.SecuritySafeCritical] static ThreadHelper() {} Delegate _start; @@ -53,10 +50,8 @@ namespace System.Threading { _executionContext = ec; } - [System.Security.SecurityCritical] static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context); - [System.Security.SecurityCritical] static private void ThreadStart_Context(Object state) { ThreadHelper t = (ThreadHelper)state; @@ -71,11 +66,6 @@ namespace System.Threading { } // call back helper - #if FEATURE_CORECLR - [System.Security.SecuritySafeCritical] // auto-generated - #else - [System.Security.SecurityCritical] - #endif internal void ThreadStart(object obj) { _startArg = obj; @@ -90,11 +80,6 @@ namespace System.Threading { } // call back helper - #if FEATURE_CORECLR - [System.Security.SecuritySafeCritical] // auto-generated - #else - [System.Security.SecurityCritical] - #endif internal void ThreadStart() { if (_executionContext != null) @@ -121,25 +106,20 @@ namespace System.Threading { // deliberately not [serializable] [ClassInterface(ClassInterfaceType.None)] [ComDefaultInterface(typeof(_Thread))] -[System.Runtime.InteropServices.ComVisible(true)] - public sealed class Thread : CriticalFinalizerObject, _Thread + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class Thread : RuntimeThread, _Thread { /*========================================================================= ** Data accessed from managed code that needs to be defined in ** ThreadBaseObject to maintain alignment between the two classes. ** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h =========================================================================*/ -#if FEATURE_REMOTING - private Context m_Context; -#endif private ExecutionContext m_ExecutionContext; // this call context follows the logical thread -#if FEATURE_CORECLR private SynchronizationContext m_SynchronizationContext; // On CoreCLR, this is maintained separately from ExecutionContext -#endif private String m_Name; private Delegate m_Delegate; // Delegate - + #if FEATURE_LEAK_CULTURE_INFO private CultureInfo m_CurrentCulture; private CultureInfo m_CurrentUICulture; @@ -212,11 +192,8 @@ namespace System.Threading { #endif // FEATURE_LEAK_CULTURE_INFO } -#if FEATURE_CORECLR // Adding an empty default ctor for annotation purposes - [System.Security.SecuritySafeCritical] // auto-generated internal Thread(){} -#endif // FEATURE_CORECLR /*========================================================================= ** Creates a new Thread object which will begin execution at @@ -224,41 +201,37 @@ namespace System.Threading { ** ** Exceptions: ArgumentNullException if start == null. =========================================================================*/ - [System.Security.SecuritySafeCritical] // auto-generated public Thread(ThreadStart start) { if (start == null) { - throw new ArgumentNullException("start"); + throw new ArgumentNullException(nameof(start)); } Contract.EndContractBlock(); SetStartHelper((Delegate)start,0); //0 will setup Thread with default stackSize } - [System.Security.SecuritySafeCritical] // auto-generated public Thread(ThreadStart start, int maxStackSize) { if (start == null) { - throw new ArgumentNullException("start"); + throw new ArgumentNullException(nameof(start)); } if (0 > maxStackSize) - throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(maxStackSize),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); SetStartHelper((Delegate)start, maxStackSize); } - [System.Security.SecuritySafeCritical] // auto-generated public Thread(ParameterizedThreadStart start) { if (start == null) { - throw new ArgumentNullException("start"); + throw new ArgumentNullException(nameof(start)); } Contract.EndContractBlock(); SetStartHelper((Delegate)start, 0); } - [System.Security.SecuritySafeCritical] // auto-generated public Thread(ParameterizedThreadStart start, int maxStackSize) { if (start == null) { - throw new ArgumentNullException("start"); + throw new ArgumentNullException(nameof(start)); } if (0 > maxStackSize) - throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(maxStackSize),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); SetStartHelper((Delegate)start, maxStackSize); } @@ -269,11 +242,10 @@ namespace System.Threading { return m_ManagedThreadId; } - extern public int ManagedThreadId + extern public new int ManagedThreadId { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [MethodImplAttribute(MethodImplOptions.InternalCall)] - [System.Security.SecuritySafeCritical] // auto-generated get; } @@ -299,17 +271,15 @@ namespace System.Threading { ** ** Exceptions: ThreadStateException if the thread has already been started. =========================================================================*/ - [HostProtection(Synchronization=true,ExternalThreading=true)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public void Start() + public new void Start() { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; Start(ref stackMark); } - [HostProtection(Synchronization=true,ExternalThreading=true)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public void Start(object parameter) + public new void Start(object parameter) { //In the case of a null delegate (second call to start on same thread) // StartInternal method will take care of the error reporting @@ -325,7 +295,6 @@ namespace System.Threading { Start(ref stackMark); } - [System.Security.SecuritySafeCritical] private void Start(ref StackCrawlMark stackMark) { #if FEATURE_COMINTEROP_APARTMENT_SUPPORT @@ -346,16 +315,11 @@ namespace System.Threading { ExecutionContext.CaptureOptions.IgnoreSyncCtx); t.SetExecutionContextHelper(ec); } -#if FEATURE_IMPERSONATION - IPrincipal principal = (IPrincipal)CallContext.Principal; -#else + IPrincipal principal = null; -#endif StartInternal(principal, ref stackMark); } - -#if FEATURE_CORECLR internal ExecutionContext ExecutionContext { get { return m_ExecutionContext; } @@ -366,89 +330,12 @@ namespace System.Threading { { get { return m_SynchronizationContext; } set { m_SynchronizationContext = value; } - } -#else // !FEATURE_CORECLR - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - internal ExecutionContext.Reader GetExecutionContextReader() - { - return new ExecutionContext.Reader(m_ExecutionContext); - } - - internal bool ExecutionContextBelongsToCurrentScope - { - get { return !m_ExecutionContextBelongsToOuterScope; } - set { m_ExecutionContextBelongsToOuterScope = !value; } - } - -#if DEBUG - internal bool ForbidExecutionContextMutation - { - set { m_ForbidExecutionContextMutation = value; } - } -#endif - - // note: please don't access this directly from mscorlib. Use GetMutableExecutionContext or GetExecutionContextReader instead. - public ExecutionContext ExecutionContext - { - [SecuritySafeCritical] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - get - { - ExecutionContext result; - if (this == Thread.CurrentThread) - result = GetMutableExecutionContext(); - else - result = m_ExecutionContext; - - return result; - } } - [SecurityCritical] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - internal ExecutionContext GetMutableExecutionContext() - { - Contract.Assert(Thread.CurrentThread == this); -#if DEBUG - Contract.Assert(!m_ForbidExecutionContextMutation); -#endif - if (m_ExecutionContext == null) - { - m_ExecutionContext = new ExecutionContext(); - } - else if (!ExecutionContextBelongsToCurrentScope) - { - ExecutionContext copy = m_ExecutionContext.CreateMutableCopy(); - m_ExecutionContext = copy; - } - - ExecutionContextBelongsToCurrentScope = true; - return m_ExecutionContext; - } - - [SecurityCritical] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - internal void SetExecutionContext(ExecutionContext value, bool belongsToCurrentScope) - { - m_ExecutionContext = value; - ExecutionContextBelongsToCurrentScope = belongsToCurrentScope; - } - - [SecurityCritical] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - internal void SetExecutionContext(ExecutionContext.Reader value, bool belongsToCurrentScope) - { - m_ExecutionContext = value.DangerousGetRawExecutionContext(); - ExecutionContextBelongsToCurrentScope = belongsToCurrentScope; - } -#endif //!FEATURE_CORECLR - - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void StartInternal(IPrincipal principal, ref StackCrawlMark stackMark); #if FEATURE_COMPRESSEDSTACK /// <internalonly/> - [System.Security.SecurityCritical] // auto-generated_required [DynamicSecurityMethodAttribute()] [Obsolete("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")] public void SetCompressedStack( CompressedStack stack ) @@ -456,17 +343,14 @@ namespace System.Threading { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported")); } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal extern IntPtr SetAppDomainStack( SafeCompressedStackHandle csHandle); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal extern void RestoreAppDomainStack( IntPtr appDomainStack); /// <internalonly/> - [System.Security.SecurityCritical] // auto-generated_required [Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")] public CompressedStack GetCompressedStack() { @@ -478,7 +362,6 @@ namespace System.Threading { // Helper method to get a logical thread ID for StringBuilder (for // correctness) and for FileStream's async code path (for perf, to // avoid creating a Thread instance). - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static IntPtr InternalGetCurrentThread(); @@ -497,34 +380,6 @@ namespace System.Threading { ** If Abort is called twice on the same thread, a DuplicateThreadAbort ** exception is thrown. =========================================================================*/ - -#if !FEATURE_CORECLR - [System.Security.SecuritySafeCritical] // auto-generated - [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)] - public void Abort(Object stateInfo) - { - // If two aborts come at the same time, it is possible that the state info - // gets set by one, and the actual abort gets delivered by another. But this - // is not distinguishable by an application. - // The accessor helper will only set the value if it isn't already set, - // and that particular bit of native code can test much faster than this - // code could, because testing might cause a cross-appdomain marshalling. - AbortReason = stateInfo; - - // Note: we demand ControlThread permission, then call AbortInternal directly - // rather than delegating to the Abort() function below. We do this to ensure - // that only callers with ControlThread are allowed to change the AbortReason - // of the thread. We call AbortInternal directly to avoid demanding the same - // permission twice. - AbortInternal(); - } -#endif - - #if FEATURE_CORECLR - [System.Security.SecurityCritical] // auto-generated - #else - [System.Security.SecuritySafeCritical] - #endif #pragma warning disable 618 [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] #pragma warning restore 618 @@ -535,152 +390,14 @@ namespace System.Threading { // Internal helper (since we can't place security demands on // ecalls/fcalls). - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void AbortInternal(); -#if !FEATURE_CORECLR - /*========================================================================= - ** Resets a thread abort. - ** Should be called by trusted code only - =========================================================================*/ - [System.Security.SecuritySafeCritical] // auto-generated - [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)] - public static void ResetAbort() - { - Thread thread = Thread.CurrentThread; - if ((thread.ThreadState & ThreadState.AbortRequested) == 0) - throw new ThreadStateException(Environment.GetResourceString("ThreadState_NoAbortRequested")); - thread.ResetAbortNative(); - thread.ClearAbortReason(); - } - - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern void ResetAbortNative(); - - /*========================================================================= - ** Suspends the thread. If the thread is already suspended, this call has - ** no effect. - ** - ** Exceptions: ThreadStateException if the thread has not been started or - ** it is dead. - =========================================================================*/ - [System.Security.SecuritySafeCritical] // auto-generated - [Obsolete("Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)][SecurityPermission(SecurityAction.Demand, ControlThread=true)] - [SecurityPermission(SecurityAction.Demand, ControlThread=true)] - public void Suspend() { SuspendInternal(); } - - // Internal helper (since we can't place security demands on - // ecalls/fcalls). - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern void SuspendInternal(); - - /*========================================================================= - ** Resumes a thread that has been suspended. - ** - ** Exceptions: ThreadStateException if the thread has not been started or - ** it is dead or it isn't in the suspended state. - =========================================================================*/ - [System.Security.SecuritySafeCritical] // auto-generated - [Obsolete("Thread.Resume has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)] - [SecurityPermission(SecurityAction.Demand, ControlThread=true)] - public void Resume() { ResumeInternal(); } - - // Internal helper (since we can't place security demands on - // ecalls/fcalls). - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern void ResumeInternal(); - - /*========================================================================= - ** Interrupts a thread that is inside a Wait(), Sleep() or Join(). If that - ** thread is not currently blocked in that manner, it will be interrupted - ** when it next begins to block. - =========================================================================*/ - [System.Security.SecuritySafeCritical] // auto-generated - [SecurityPermission(SecurityAction.Demand, ControlThread=true)] - public void Interrupt() { InterruptInternal(); } - - // Internal helper (since we can't place security demands on - // ecalls/fcalls). - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern void InterruptInternal(); -#endif - - /*========================================================================= - ** Returns the priority of the thread. - ** - ** Exceptions: ThreadStateException if the thread is dead. - =========================================================================*/ - - public ThreadPriority Priority { - [System.Security.SecuritySafeCritical] // auto-generated - get { return (ThreadPriority)GetPriorityNative(); } - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(SelfAffectingThreading=true)] - set { SetPriorityNative((int)value); } - } - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern int GetPriorityNative(); - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern void SetPriorityNative(int priority); - - /*========================================================================= - ** Returns true if the thread has been started and is not dead. - =========================================================================*/ - public extern bool IsAlive { - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImpl(MethodImplOptions.InternalCall)] - get; - } - - /*========================================================================= - ** Returns true if the thread is a threadpool thread. - =========================================================================*/ - public extern bool IsThreadPoolThread { - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImpl(MethodImplOptions.InternalCall)] - get; - } - - /*========================================================================= - ** Waits for the thread to die or for timeout milliseconds to elapse. - ** Returns true if the thread died, or false if the wait timed out. If - ** Timeout.Infinite is given as the parameter, no timeout will occur. - ** - ** Exceptions: ArgumentException if timeout < 0. - ** ThreadInterruptedException if the thread is interrupted while waiting. - ** ThreadStateException if the thread has not been started yet. - =========================================================================*/ - [System.Security.SecurityCritical] - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern bool JoinInternal(int millisecondsTimeout); - - [System.Security.SecuritySafeCritical] - [HostProtection(Synchronization=true, ExternalThreading=true)] - public void Join() - { - JoinInternal(Timeout.Infinite); - } - - [System.Security.SecuritySafeCritical] - [HostProtection(Synchronization=true, ExternalThreading=true)] - public bool Join(int millisecondsTimeout) - { - return JoinInternal(millisecondsTimeout); - } - - [HostProtection(Synchronization=true, ExternalThreading=true)] public bool Join(TimeSpan timeout) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); return Join((int)tm); } @@ -693,12 +410,10 @@ namespace System.Threading { ** Exceptions: ArgumentException if timeout < 0. ** ThreadInterruptedException if the thread is interrupted while sleeping. =========================================================================*/ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void SleepInternal(int millisecondsTimeout); - [System.Security.SecuritySafeCritical] // auto-generated - public static void Sleep(int millisecondsTimeout) + public static new void Sleep(int millisecondsTimeout) { SleepInternal(millisecondsTimeout); // Ensure we don't return to app code when the pause is underway @@ -710,7 +425,7 @@ namespace System.Threading { { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); Sleep((int)tm); } @@ -719,69 +434,41 @@ namespace System.Threading { only take a few machine instructions. Calling this API is preferable to coding a explict busy loop because the hardware can be informed that it is busy waiting. */ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] - [HostProtection(Synchronization=true,ExternalThreading=true)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private static extern void SpinWaitInternal(int iterations); - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(Synchronization=true,ExternalThreading=true)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - public static void SpinWait(int iterations) + public static new void SpinWait(int iterations) { SpinWaitInternal(iterations); } - [System.Security.SecurityCritical] // auto-generated [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] - [HostProtection(Synchronization = true, ExternalThreading = true)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private static extern bool YieldInternal(); - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(Synchronization = true, ExternalThreading = true)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - public static bool Yield() + public static new bool Yield() { return YieldInternal(); } - public static Thread CurrentThread { - [System.Security.SecuritySafeCritical] // auto-generated + public static new Thread CurrentThread { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] get { Contract.Ensures(Contract.Result<Thread>() != null); return GetCurrentThreadNative(); } } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private static extern Thread GetCurrentThreadNative(); - [System.Security.SecurityCritical] // auto-generated private void SetStartHelper(Delegate start, int maxStackSize) { -#if FEATURE_CORECLR // We only support default stacks in CoreCLR - Contract.Assert(maxStackSize == 0); -#else - // Only fully-trusted code is allowed to create "large" stacks. Partial-trust falls back to - // the default stack size. - ulong defaultStackSize = GetProcessDefaultStackSize(); - if ((ulong)(uint)maxStackSize > defaultStackSize) - { - try - { - SecurityPermission.Demand(PermissionType.FullTrust); - } - catch (SecurityException) - { - maxStackSize = (int)Math.Min(defaultStackSize, (ulong)(uint)int.MaxValue); - } - } -#endif + Debug.Assert(maxStackSize == 0); ThreadHelper threadStartCallBack = new ThreadHelper(start); if(start is ThreadStart) @@ -794,7 +481,6 @@ namespace System.Threading { } } - [SecurityCritical] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern ulong GetProcessDefaultStackSize(); @@ -803,14 +489,12 @@ namespace System.Threading { ** PRIVATE Sets the IThreadable interface for the thread. Assumes that ** start != null. =========================================================================*/ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void SetStart(Delegate start, int maxStackSize); /*========================================================================= ** Clean up the thread when it goes away. =========================================================================*/ - [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] ~Thread() { @@ -818,52 +502,10 @@ namespace System.Threading { InternalFinalize(); } - [System.Security.SecurityCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void InternalFinalize(); -#if FEATURE_COMINTEROP - [System.Security.SecurityCritical] // auto-generated - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [MethodImplAttribute(MethodImplOptions.InternalCall)] - public extern void DisableComObjectEagerCleanup(); -#endif //FEATURE_COMINTEROP - - /*========================================================================= - ** Return whether or not this thread is a background thread. Background - ** threads do not affect when the Execution Engine shuts down. - ** - ** Exceptions: ThreadStateException if the thread is dead. - =========================================================================*/ - public bool IsBackground { - [System.Security.SecuritySafeCritical] // auto-generated - get { return IsBackgroundNative(); } - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(SelfAffectingThreading=true)] - set { SetBackgroundNative(value); } - } - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern bool IsBackgroundNative(); - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern void SetBackgroundNative(bool isBackground); - - - /*========================================================================= - ** Return the thread state as a consistent set of bits. This is more - ** general then IsAlive or IsBackground. - =========================================================================*/ - public ThreadState ThreadState { - [System.Security.SecuritySafeCritical] // auto-generated - get { return (ThreadState)GetThreadStateNative(); } - } - - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern int GetThreadStateNative(); - #if FEATURE_COMINTEROP_APARTMENT_SUPPORT /*========================================================================= ** An unstarted thread can be marked to indicate that it will host a @@ -875,35 +517,17 @@ namespace System.Threading { [Obsolete("The ApartmentState property has been deprecated. Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)] public ApartmentState ApartmentState { - [System.Security.SecuritySafeCritical] // auto-generated get { return (ApartmentState)GetApartmentStateNative(); } - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(Synchronization=true, SelfAffectingThreading=true)] set { SetApartmentStateNative((int)value, true); } } - [System.Security.SecuritySafeCritical] // auto-generated - public ApartmentState GetApartmentState() - { - return (ApartmentState)GetApartmentStateNative(); - } - - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(Synchronization=true, SelfAffectingThreading=true)] - public bool TrySetApartmentState(ApartmentState state) - { - return SetApartmentStateHelper(state, false); - } - - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(Synchronization=true, SelfAffectingThreading=true)] public void SetApartmentState(ApartmentState state) { bool result = SetApartmentStateHelper(state, true); @@ -911,31 +535,6 @@ namespace System.Threading { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ApartmentStateSwitchFailed")); } - [System.Security.SecurityCritical] // auto-generated - private bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch) - { - ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state, fireMDAOnMismatch); - - // Special case where we pass in Unknown and get back MTA. - // Once we CoUninitialize the thread, the OS will still - // report the thread as implicitly in the MTA if any - // other thread in the process is CoInitialized. - if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA)) - return true; - - if (retState != state) - return false; - - return true; - } - - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern int GetApartmentStateNative(); - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void StartupSetApartmentStateInternal(); #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT @@ -944,7 +543,6 @@ namespace System.Threading { ** Allocates an un-named data slot. The slot is allocated on ALL the ** threads. =========================================================================*/ - [HostProtection(SharedState=true, ExternalThreading=true)] public static LocalDataStoreSlot AllocateDataSlot() { return LocalDataStoreManager.AllocateDataSlot(); @@ -955,7 +553,6 @@ namespace System.Threading { ** threads. Named data slots are "public" and can be manipulated by ** anyone. =========================================================================*/ - [HostProtection(SharedState=true, ExternalThreading=true)] public static LocalDataStoreSlot AllocateNamedDataSlot(String name) { return LocalDataStoreManager.AllocateNamedDataSlot(name); @@ -966,7 +563,6 @@ namespace System.Threading { ** allocated. Named data slots are "public" and can be manipulated by ** anyone. =========================================================================*/ - [HostProtection(SharedState=true, ExternalThreading=true)] public static LocalDataStoreSlot GetNamedDataSlot(String name) { return LocalDataStoreManager.GetNamedDataSlot(name); @@ -977,7 +573,6 @@ namespace System.Threading { ** threads. Named data slots are "public" and can be manipulated by ** anyone. =========================================================================*/ - [HostProtection(SharedState=true, ExternalThreading=true)] public static void FreeNamedDataSlot(String name) { LocalDataStoreManager.FreeNamedDataSlot(name); @@ -986,7 +581,6 @@ namespace System.Threading { /*========================================================================= ** Retrieves the value from the specified slot on the current thread, for that thread's current domain. =========================================================================*/ - [HostProtection(SharedState=true, ExternalThreading=true)] public static Object GetData(LocalDataStoreSlot slot) { LocalDataStoreHolder dls = s_LocalDataStore; @@ -1003,7 +597,6 @@ namespace System.Threading { /*========================================================================= ** Sets the data in the specified slot on the currently running thread, for that thread's current domain. =========================================================================*/ - [HostProtection(SharedState=true, ExternalThreading=true)] public static void SetData(LocalDataStoreSlot slot, Object data) { LocalDataStoreHolder dls = s_LocalDataStore; @@ -1044,7 +637,6 @@ namespace System.Threading { // default domain to lookup resources. See Environment.cs for more details. // #if FEATURE_LEAK_CULTURE_INFO - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private bool nativeGetSafeCulture(Thread t, int appDomainId, bool isUI, ref CultureInfo safeCulture); #endif // FEATURE_LEAK_CULTURE_INFO @@ -1075,11 +667,9 @@ namespace System.Threading { } } - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(ExternalThreading=true)] set { if (value == null) { - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); } Contract.EndContractBlock(); @@ -1119,7 +709,6 @@ namespace System.Threading { } #if FEATURE_LEAK_CULTURE_INFO - [System.Security.SecuritySafeCritical] // auto-generated #endif internal CultureInfo GetCurrentUICultureNoAppX() { @@ -1152,7 +741,6 @@ namespace System.Threading { // This returns the exposed context for a given context ID. #if FEATURE_LEAK_CULTURE_INFO - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private bool nativeSetThreadUILocale(String locale); #endif @@ -1184,13 +772,11 @@ namespace System.Threading { } } - [System.Security.SecuritySafeCritical] // auto-generated #if FEATURE_LEAK_CULTURE_INFO - [SecurityPermission(SecurityAction.Demand, ControlThread = true)] #endif set { if (null==value) { - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); } Contract.EndContractBlock(); @@ -1225,7 +811,6 @@ namespace System.Threading { } #if FEATURE_LEAK_CULTURE_INFO - [System.Security.SecuritySafeCritical] // auto-generated #endif private CultureInfo GetCurrentCultureNoAppX() { @@ -1255,114 +840,21 @@ namespace System.Threading { #endif } -#if! FEATURE_LEAK_CULTURE_INFO - [System.Security.SecurityCritical] // auto-generated +#if !FEATURE_LEAK_CULTURE_INFO [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void nativeInitCultureAccessors(); #endif - /*=============================================================*/ - - /*====================================================================== - ** Current thread context is stored in a slot in the thread local store - ** CurrentContext gets the Context from the slot. - ======================================================================*/ -#if FEATURE_REMOTING - public static Context CurrentContext - { - [System.Security.SecurityCritical] // auto-generated_required - get - { - return CurrentThread.GetCurrentContextInternal(); - } - } - - [System.Security.SecurityCritical] // auto-generated - internal Context GetCurrentContextInternal() - { - if (m_Context == null) - { - m_Context = Context.DefaultContext; - } - return m_Context; - } -#endif - - -#if FEATURE_IMPERSONATION - // Get and set thread's current principal (for role based security). - public static IPrincipal CurrentPrincipal - { - [System.Security.SecuritySafeCritical] // auto-generated - get - { - lock (CurrentThread) - { - IPrincipal principal = (IPrincipal) - CallContext.Principal; - if (principal == null) - { - principal = GetDomain().GetThreadPrincipal(); - CallContext.Principal = principal; - } - return principal; - } - } - - [System.Security.SecuritySafeCritical] // auto-generated - [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] - set - { - CallContext.Principal = value; - } - } - - // Private routine called from unmanaged code to set an initial - // principal for a newly created thread. - [System.Security.SecurityCritical] // auto-generated - private void SetPrincipalInternal(IPrincipal principal) - { - GetMutableExecutionContext().LogicalCallContext.SecurityData.Principal = principal; - } -#endif // FEATURE_IMPERSONATION - -#if FEATURE_REMOTING - - // This returns the exposed context for a given context ID. - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern Context GetContextInternal(IntPtr id); - - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal extern Object InternalCrossContextCallback(Context ctx, IntPtr ctxID, Int32 appDomainID, InternalCrossContextDelegate ftnToCall, Object[] args); - - [System.Security.SecurityCritical] // auto-generated - internal Object InternalCrossContextCallback(Context ctx, InternalCrossContextDelegate ftnToCall, Object[] args) - { - return InternalCrossContextCallback(ctx, ctx.InternalContextID, 0, ftnToCall, args); - } - - // CompleteCrossContextCallback is called by the EE after transitioning to the requested context - private static Object CompleteCrossContextCallback(InternalCrossContextDelegate ftnToCall, Object[] args) - { - return ftnToCall(args); - } -#endif // FEATURE_REMOTING - /*====================================================================== ** Returns the current domain in which current thread is running. ======================================================================*/ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern AppDomain GetDomainInternal(); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern AppDomain GetFastDomainInternal(); - [System.Security.SecuritySafeCritical] // auto-generated public static AppDomain GetDomain() { Contract.Ensures(Contract.Result<AppDomain>() != null); @@ -1373,9 +865,6 @@ namespace System.Threading { if (ad == null) ad = GetDomainInternal(); -#if FEATURE_REMOTING - Contract.Assert(CurrentThread.m_Context == null || CurrentThread.m_Context.AppDomain == ad, "AppDomains on the managed & unmanaged threads should match"); -#endif return ad; } @@ -1391,13 +880,10 @@ namespace System.Threading { // Retrieves the name of the thread. // - public String Name { + public new String Name { get { return m_Name; - } - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(ExternalThreading=true)] set { lock(this) { if (m_Name != null) @@ -1409,13 +895,11 @@ namespace System.Threading { } } - [System.Security.SecurityCritical] // auto-generated [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void InformThreadNameChange(ThreadHandle t, String name, int len); internal Object AbortReason { - [System.Security.SecurityCritical] // auto-generated get { object result = null; try @@ -1428,46 +912,9 @@ namespace System.Threading { } return result; } - [System.Security.SecurityCritical] // auto-generated set { SetAbortReason(value); } } -#if !FEATURE_CORECLR - /* - * This marks the beginning of a critical code region. - */ - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(Synchronization=true, ExternalThreading=true)] - [MethodImplAttribute(MethodImplOptions.InternalCall)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - public static extern void BeginCriticalRegion(); - - /* - * This marks the end of a critical code region. - */ - [System.Security.SecuritySafeCritical] // auto-generated - [HostProtection(Synchronization=true, ExternalThreading=true)] - [MethodImplAttribute(MethodImplOptions.InternalCall)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - public static extern void EndCriticalRegion(); - - /* - * This marks the beginning of a code region that requires thread affinity. - */ - [System.Security.SecurityCritical] // auto-generated_required - [MethodImplAttribute(MethodImplOptions.InternalCall)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - public static extern void BeginThreadAffinity(); - - /* - * This marks the end of a code region that requires thread affinity. - */ - [System.Security.SecurityCritical] // auto-generated_required - [MethodImplAttribute(MethodImplOptions.InternalCall)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - public static extern void EndThreadAffinity(); -#endif // !FEATURE_CORECLR - /*========================================================================= ** Volatile Read & Write and MemoryBarrier methods. ** Provides the ability to read and write values ensuring that the values @@ -1679,7 +1126,6 @@ namespace System.Threading { address = value; } - [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern void MemoryBarrier(); @@ -1696,45 +1142,20 @@ namespace System.Threading { } } -#if !FEATURE_CORECLR - void _Thread.GetTypeInfoCount(out uint pcTInfo) - { - throw new NotImplementedException(); - } - - void _Thread.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) - { - throw new NotImplementedException(); - } - - void _Thread.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) - { - throw new NotImplementedException(); - } - - void _Thread.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) - { - throw new NotImplementedException(); - } -#endif - // Helper function to set the AbortReason for a thread abort. // Checks that they're not alredy set, and then atomically updates // the reason info (object + ADID). - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern void SetAbortReason(Object o); // Helper function to retrieve the AbortReason from a thread // abort. Will perform cross-AppDomain marshalling if the object // lives in a different AppDomain from the requester. - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern Object GetAbortReason(); // Helper function to clear the AbortReason. Takes care of // AppDomain related cleanup if required. - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern void ClearAbortReason(); diff --git a/src/mscorlib/src/System/Threading/ThreadAbortException.cs b/src/mscorlib/src/System/Threading/ThreadAbortException.cs index 11c8744c72..09ad4e1bd6 100644 --- a/src/mscorlib/src/System/Threading/ThreadAbortException.cs +++ b/src/mscorlib/src/System/Threading/ThreadAbortException.cs @@ -39,7 +39,6 @@ namespace System.Threading public Object ExceptionState { - [System.Security.SecuritySafeCritical] // auto-generated get {return Thread.CurrentThread.AbortReason;} } } diff --git a/src/mscorlib/src/System/Threading/ThreadLocal.cs b/src/mscorlib/src/System/Threading/ThreadLocal.cs index b4cf12ab7c..2b996cb34d 100644 --- a/src/mscorlib/src/System/Threading/ThreadLocal.cs +++ b/src/mscorlib/src/System/Threading/ThreadLocal.cs @@ -15,9 +15,9 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -using System.Diagnostics; using System.Collections.Generic; using System.Security.Permissions; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace System.Threading @@ -35,7 +35,6 @@ namespace System.Threading /// </remarks> [DebuggerTypeProxy(typeof(SystemThreading_ThreadLocalDebugView<>))] [DebuggerDisplay("IsValueCreated={IsValueCreated}, Value={ValueForDebugDisplay}, Count={ValuesCountForDebugDisplay}")] - [HostProtection(Synchronization = true, ExternalThreading = true)] public class ThreadLocal<T> : IDisposable { @@ -107,7 +106,7 @@ namespace System.Threading public ThreadLocal(Func<T> valueFactory) { if (valueFactory == null) - throw new ArgumentNullException("valueFactory"); + throw new ArgumentNullException(nameof(valueFactory)); Initialize(valueFactory, false); } @@ -127,7 +126,7 @@ namespace System.Threading public ThreadLocal(Func<T> valueFactory, bool trackAllValues) { if (valueFactory == null) - throw new ArgumentNullException("valueFactory"); + throw new ArgumentNullException(nameof(valueFactory)); Initialize(valueFactory, trackAllValues); } @@ -193,7 +192,7 @@ namespace System.Threading if (id < 0 || !m_initialized) { - Contract.Assert(id >= 0 || !m_initialized, "expected id >= 0 if initialized"); + Debug.Assert(id >= 0 || !m_initialized, "expected id >= 0 if initialized"); // Handle double Dispose calls or disposal of an instance whose constructor threw an exception. return; @@ -550,7 +549,7 @@ namespace System.Threading /// </summary> private void GrowTable(ref LinkedSlotVolatile[] table, int minLength) { - Contract.Assert(table.Length < minLength); + Debug.Assert(table.Length < minLength); // Determine the size of the new table and allocate it. int newLen = GetNewTableSize(minLength); @@ -588,7 +587,7 @@ namespace System.Threading // Intentionally return a value that will result in an OutOfMemoryException return int.MaxValue; } - Contract.Assert(minSize > 0); + Debug.Assert(minSize > 0); // // Round up the size to the next power of 2 @@ -737,7 +736,7 @@ namespace System.Threading ~FinalizationHelper() { LinkedSlotVolatile[] slotArray = SlotArray; - Contract.Assert(slotArray != null); + Debug.Assert(slotArray != null); for (int i = 0; i < slotArray.Length; i++) { @@ -765,7 +764,7 @@ namespace System.Threading } // Since the list uses a dummy head node, the Previous reference should never be null. - Contract.Assert(linkedSlot.Previous != null); + Debug.Assert(linkedSlot.Previous != null); linkedSlot.Previous.Next = linkedSlot.Next; } } diff --git a/src/mscorlib/src/System/Threading/ThreadPool.cs b/src/mscorlib/src/System/Threading/ThreadPool.cs index 09fe93c682..451b15d22f 100644 --- a/src/mscorlib/src/System/Threading/ThreadPool.cs +++ b/src/mscorlib/src/System/Threading/ThreadPool.cs @@ -29,15 +29,14 @@ namespace System.Threading { using System.Security; - using System.Runtime.Remoting; using System.Security.Permissions; using System; using Microsoft.Win32; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; - using System.Runtime.Versioning; using System.Collections.Generic; + using System.Diagnostics; using System.Diagnostics.Contracts; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Tracing; @@ -46,19 +45,17 @@ namespace System.Threading { //Per-appDomain quantum (in ms) for which the thread keeps processing //requests in the current domain. - public static uint tpQuantum = 30U; + public const uint TP_QUANTUM = 30U; - public static int processorCount = Environment.ProcessorCount; + public static readonly int processorCount = Environment.ProcessorCount; - public static bool tpHosted = ThreadPool.IsThreadPoolHosted(); + public static readonly bool tpHosted = ThreadPool.IsThreadPoolHosted(); public static volatile bool vmTpInitialized; public static bool enableWorkerTracking; - [SecurityCritical] - public static ThreadPoolWorkQueue workQueue = new ThreadPoolWorkQueue(); + public static readonly ThreadPoolWorkQueue workQueue = new ThreadPoolWorkQueue(); - [System.Security.SecuritySafeCritical] // static constructors should be safe to call static ThreadPoolGlobals() { } @@ -173,7 +170,7 @@ namespace System.Threading // m_headIndex = m_headIndex & m_mask; m_tailIndex = tail = m_tailIndex & m_mask; - Contract.Assert(m_headIndex <= m_tailIndex); + Debug.Assert(m_headIndex <= m_tailIndex); } } finally @@ -235,7 +232,7 @@ namespace System.Threading IThreadPoolWorkItem unused; if (LocalPop(out unused)) { - Contract.Assert(unused == obj); + Debug.Assert(unused == obj); return true; } return false; @@ -434,23 +431,23 @@ namespace System.Threading upper = (i >> 16) & SixteenBits; lower = i & SixteenBits; - Contract.Assert(upper >= lower); - Contract.Assert(upper <= nodes.Length); - Contract.Assert(lower <= nodes.Length); - Contract.Assert(upper >= 0); - Contract.Assert(lower >= 0); + Debug.Assert(upper >= lower); + Debug.Assert(upper <= nodes.Length); + Debug.Assert(lower <= nodes.Length); + Debug.Assert(upper >= 0); + Debug.Assert(lower >= 0); } bool CompareExchangeIndexes(ref int prevUpper, int newUpper, ref int prevLower, int newLower) { - Contract.Assert(newUpper >= newLower); - Contract.Assert(newUpper <= nodes.Length); - Contract.Assert(newLower <= nodes.Length); - Contract.Assert(newUpper >= 0); - Contract.Assert(newLower >= 0); - Contract.Assert(newUpper >= prevUpper); - Contract.Assert(newLower >= prevLower); - Contract.Assert(newUpper == prevUpper ^ newLower == prevLower); + Debug.Assert(newUpper >= newLower); + Debug.Assert(newUpper <= nodes.Length); + Debug.Assert(newLower <= nodes.Length); + Debug.Assert(newUpper >= 0); + Debug.Assert(newLower >= 0); + Debug.Assert(newUpper >= prevUpper); + Debug.Assert(newLower >= prevLower); + Debug.Assert(newUpper == prevUpper ^ newLower == prevLower); int oldIndexes = (prevUpper << 16) | (prevLower & SixteenBits); int newIndexes = (newUpper << 16) | (newLower & SixteenBits); @@ -463,7 +460,7 @@ namespace System.Threading [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public QueueSegment() { - Contract.Assert(QueueSegmentLength <= SixteenBits); + Debug.Assert(QueueSegmentLength <= SixteenBits); nodes = new IThreadPoolWorkItem[QueueSegmentLength]; } @@ -486,7 +483,7 @@ namespace System.Threading // with a busy-wait loop, waiting for the element to become non-null. This implies // that we can never store null nodes in this data structure. // - Contract.Assert(null != node); + Debug.Assert(null != node); int upper, lower; GetIndexes(out upper, out lower); @@ -498,7 +495,7 @@ namespace System.Threading if (CompareExchangeIndexes(ref upper, upper + 1, ref lower, lower)) { - Contract.Assert(Volatile.Read(ref nodes[upper]) == null); + Debug.Assert(Volatile.Read(ref nodes[upper]) == null); Volatile.Write(ref nodes[upper], node); return true; } @@ -546,7 +543,7 @@ namespace System.Threading internal volatile QueueSegment queueTail; internal bool loggingEnabled; - internal static SparseArray<WorkStealingQueue> allThreadQueues = new SparseArray<WorkStealingQueue>(16); + internal static readonly SparseArray<WorkStealingQueue> allThreadQueues = new SparseArray<WorkStealingQueue>(16); private volatile int numOutstandingThreadRequests = 0; @@ -556,7 +553,6 @@ namespace System.Threading loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool|FrameworkEventSource.Keywords.ThreadTransfer); } - [SecurityCritical] public ThreadPoolWorkQueueThreadLocals EnsureCurrentThreadHasQueue() { if (null == ThreadPoolWorkQueueThreadLocals.threadLocals) @@ -564,7 +560,6 @@ namespace System.Threading return ThreadPoolWorkQueueThreadLocals.threadLocals; } - [SecurityCritical] internal void EnsureThreadRequested() { // @@ -585,7 +580,6 @@ namespace System.Threading } } - [SecurityCritical] internal void MarkThreadRequestSatisfied() { // @@ -606,7 +600,6 @@ namespace System.Threading } } - [SecurityCritical] public void Enqueue(IThreadPoolWorkItem callback, bool forceGlobal) { ThreadPoolWorkQueueThreadLocals tl = null; @@ -639,7 +632,6 @@ namespace System.Threading EnsureThreadRequested(); } - [SecurityCritical] internal bool LocalFindAndPop(IThreadPoolWorkItem callback) { ThreadPoolWorkQueueThreadLocals tl = ThreadPoolWorkQueueThreadLocals.threadLocals; @@ -649,7 +641,6 @@ namespace System.Threading return tl.workStealingQueue.LocalFindAndPop(callback); } - [SecurityCritical] public void Dequeue(ThreadPoolWorkQueueThreadLocals tl, out IThreadPoolWorkItem callback, out bool missedSteal) { callback = null; @@ -657,7 +648,7 @@ namespace System.Threading WorkStealingQueue wsq = tl.workStealingQueue; if (wsq.LocalPop(out callback)) - Contract.Assert(null != callback); + Debug.Assert(null != callback); if (null == callback) { @@ -666,7 +657,7 @@ namespace System.Threading { if (tail.TryDequeue(out callback)) { - Contract.Assert(null != callback); + Debug.Assert(null != callback); break; } @@ -696,7 +687,7 @@ namespace System.Threading otherQueue != wsq && otherQueue.TrySteal(out callback, ref missedSteal)) { - Contract.Assert(null != callback); + Debug.Assert(null != callback); break; } c--; @@ -704,12 +695,11 @@ namespace System.Threading } } - [SecurityCritical] static internal bool Dispatch() { var workQueue = ThreadPoolGlobals.workQueue; // - // The clock is ticking! We have ThreadPoolGlobals.tpQuantum milliseconds to get some work done, and then + // The clock is ticking! We have ThreadPoolGlobals.TP_QUANTUM milliseconds to get some work done, and then // we need to return to the VM. // int quantumStartTime = Environment.TickCount; @@ -743,7 +733,7 @@ namespace System.Threading // // Loop until our quantum expires. // - while ((Environment.TickCount - quantumStartTime) < ThreadPoolGlobals.tpQuantum) + while ((Environment.TickCount - quantumStartTime) < ThreadPoolGlobals.TP_QUANTUM) { // // Dequeue and EnsureThreadRequested must be protected from ThreadAbortException. @@ -855,7 +845,7 @@ namespace System.Threading } // we can never reach this point, but the C# compiler doesn't know that, because it doesn't know the ThreadAbortException will be reraised above. - Contract.Assert(false); + Debug.Assert(false); return true; } } @@ -864,7 +854,6 @@ namespace System.Threading internal sealed class ThreadPoolWorkQueueThreadLocals { [ThreadStatic] - [SecurityCritical] public static ThreadPoolWorkQueueThreadLocals threadLocals; public readonly ThreadPoolWorkQueue workQueue; @@ -878,7 +867,6 @@ namespace System.Threading ThreadPoolWorkQueue.allThreadQueues.Add(workStealingQueue); } - [SecurityCritical] private void CleanUp() { if (null != workStealingQueue) @@ -895,7 +883,7 @@ namespace System.Threading IThreadPoolWorkItem cb = null; if (workStealingQueue.LocalPop(out cb)) { - Contract.Assert(null != cb); + Debug.Assert(null != cb); workQueue.Enqueue(cb, true); } else @@ -910,7 +898,6 @@ namespace System.Threading } } - [SecuritySafeCritical] ~ThreadPoolWorkQueueThreadLocals() { // Since the purpose of calling CleanUp is to transfer any pending workitems into the global @@ -927,7 +914,6 @@ namespace System.Threading { private static IntPtr InvalidHandle { - [System.Security.SecuritySafeCritical] // auto-generated get { return Win32Native.INVALID_HANDLE_VALUE; @@ -938,9 +924,6 @@ namespace System.Threading private bool bReleaseNeeded = false; private volatile int m_lock = 0; - #if FEATURE_CORECLR - [System.Security.SecuritySafeCritical] // auto-generated - #endif internal RegisteredWaitHandleSafe() { registeredWaitHandle = InvalidHandle; @@ -956,7 +939,6 @@ namespace System.Threading registeredWaitHandle = handle; } - [System.Security.SecurityCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal void SetWaitObject(WaitHandle waitObject) { @@ -975,7 +957,6 @@ namespace System.Threading } } - [System.Security.SecurityCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal bool Unregister( WaitHandle waitObject // object to be notified when all callbacks to delegates have completed @@ -1033,7 +1014,6 @@ namespace System.Threading return (registeredWaitHandle != InvalidHandle && registeredWaitHandle != IntPtr.Zero); } - [System.Security.SecuritySafeCritical] // auto-generated ~RegisteredWaitHandleSafe() { // if the app has already unregistered the wait, there is nothing to cleanup @@ -1084,21 +1064,15 @@ namespace System.Threading } } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void WaitHandleCleanupNative(IntPtr handle); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool UnregisterWaitNative(IntPtr handle, SafeHandle waitObject); } [System.Runtime.InteropServices.ComVisible(true)] -#if FEATURE_REMOTING public sealed class RegisteredWaitHandle : MarshalByRefObject { -#else // FEATURE_REMOTING - public sealed class RegisteredWaitHandle { -#endif // FEATURE_REMOTING private RegisteredWaitHandleSafe internalRegisteredWait; internal RegisteredWaitHandle() @@ -1111,14 +1085,12 @@ namespace System.Threading internalRegisteredWait.SetHandle(handle); } - [System.Security.SecurityCritical] // auto-generated internal void SetWaitObject(WaitHandle waitObject) { internalRegisteredWait.SetWaitObject(waitObject); } -[System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(true)] // This is the only public method on this class public bool Unregister( @@ -1143,7 +1115,6 @@ namespace System.Threading // internal static class _ThreadPoolWaitCallback { - [System.Security.SecurityCritical] static internal bool PerformWaitCallback() { return ThreadPoolWorkQueue.Dispatch(); @@ -1161,15 +1132,12 @@ namespace System.Threading // internal interface IThreadPoolWorkItem { - [SecurityCritical] void ExecuteWorkItem(); - [SecurityCritical] void MarkAborted(ThreadAbortException tae); } internal sealed class QueueUserWorkItemCallback : IThreadPoolWorkItem { - [System.Security.SecuritySafeCritical] static QueueUserWorkItemCallback() {} private WaitCallback callback; @@ -1181,7 +1149,7 @@ namespace System.Threading ~QueueUserWorkItemCallback() { - Contract.Assert( + Debug.Assert( executed != 0 || Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload(), "A QueueUserWorkItemCallback was never called!"); } @@ -1189,13 +1157,12 @@ namespace System.Threading void MarkExecuted(bool aborted) { GC.SuppressFinalize(this); - Contract.Assert( + Debug.Assert( 0 == Interlocked.Exchange(ref executed, 1) || aborted, "A QueueUserWorkItemCallback was called twice!"); } #endif - [SecurityCritical] internal QueueUserWorkItemCallback(WaitCallback waitCallback, Object stateObj, ExecutionContext ec) { callback = waitCallback; @@ -1203,7 +1170,6 @@ namespace System.Threading context = ec; } - [SecurityCritical] void IThreadPoolWorkItem.ExecuteWorkItem() { #if DEBUG @@ -1222,7 +1188,6 @@ namespace System.Threading } } - [SecurityCritical] void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { #if DEBUG @@ -1232,22 +1197,19 @@ namespace System.Threading #endif } - [System.Security.SecurityCritical] static internal ContextCallback ccb = new ContextCallback(WaitCallback_Context); - [System.Security.SecurityCritical] static private void WaitCallback_Context(Object state) { QueueUserWorkItemCallback obj = (QueueUserWorkItemCallback)state; WaitCallback wc = obj.callback as WaitCallback; - Contract.Assert(null != wc); + Debug.Assert(null != wc); wc(obj.state); } } internal sealed class QueueUserWorkItemCallbackDefaultContext : IThreadPoolWorkItem { - [System.Security.SecuritySafeCritical] static QueueUserWorkItemCallbackDefaultContext() { } private WaitCallback callback; @@ -1258,7 +1220,7 @@ namespace System.Threading ~QueueUserWorkItemCallbackDefaultContext() { - Contract.Assert( + Debug.Assert( executed != 0 || Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload(), "A QueueUserWorkItemCallbackDefaultContext was never called!"); } @@ -1266,20 +1228,18 @@ namespace System.Threading void MarkExecuted(bool aborted) { GC.SuppressFinalize(this); - Contract.Assert( + Debug.Assert( 0 == Interlocked.Exchange(ref executed, 1) || aborted, "A QueueUserWorkItemCallbackDefaultContext was called twice!"); } #endif - [SecurityCritical] internal QueueUserWorkItemCallbackDefaultContext(WaitCallback waitCallback, Object stateObj) { callback = waitCallback; state = stateObj; } - [SecurityCritical] void IThreadPoolWorkItem.ExecuteWorkItem() { #if DEBUG @@ -1288,7 +1248,6 @@ namespace System.Threading ExecutionContext.Run(ExecutionContext.PreAllocatedDefault, ccb, this, true); } - [SecurityCritical] void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { #if DEBUG @@ -1298,15 +1257,13 @@ namespace System.Threading #endif } - [System.Security.SecurityCritical] static internal ContextCallback ccb = new ContextCallback(WaitCallback_Context); - [System.Security.SecurityCritical] static private void WaitCallback_Context(Object state) { QueueUserWorkItemCallbackDefaultContext obj = (QueueUserWorkItemCallbackDefaultContext)state; WaitCallback wc = obj.callback as WaitCallback; - Contract.Assert(null != wc); + Debug.Assert(null != wc); obj.callback = null; wc(obj.state); } @@ -1314,18 +1271,14 @@ namespace System.Threading internal class _ThreadPoolWaitOrTimerCallback { - [System.Security.SecuritySafeCritical] static _ThreadPoolWaitOrTimerCallback() {} WaitOrTimerCallback _waitOrTimerCallback; ExecutionContext _executionContext; Object _state; - [System.Security.SecurityCritical] static private ContextCallback _ccbt = new ContextCallback(WaitOrTimerCallback_Context_t); - [System.Security.SecurityCritical] static private ContextCallback _ccbf = new ContextCallback(WaitOrTimerCallback_Context_f); - [System.Security.SecurityCritical] // auto-generated internal _ThreadPoolWaitOrTimerCallback(WaitOrTimerCallback waitOrTimerCallback, Object state, bool compressStack, ref StackCrawlMark stackMark) { _waitOrTimerCallback = waitOrTimerCallback; @@ -1340,13 +1293,11 @@ namespace System.Threading } } - [System.Security.SecurityCritical] static private void WaitOrTimerCallback_Context_t(Object state) { WaitOrTimerCallback_Context(state, true); } - [System.Security.SecurityCritical] static private void WaitOrTimerCallback_Context_f(Object state) { WaitOrTimerCallback_Context(state, false); @@ -1359,11 +1310,10 @@ namespace System.Threading } // call back helper - [System.Security.SecurityCritical] // auto-generated static internal void PerformWaitOrTimerCallback(Object state, bool timedOut) { _ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state; - Contract.Assert(helper != null, "Null state passed to PerformWaitOrTimerCallback!"); + Debug.Assert(helper != null, "Null state passed to PerformWaitOrTimerCallback!"); // call directly if it is an unsafe call OR EC flow is suppressed if (helper._executionContext == null) { @@ -1384,7 +1334,6 @@ namespace System.Threading } - [System.Security.SecurityCritical] [CLSCompliant(false)] [System.Runtime.InteropServices.ComVisible(true)] unsafe public delegate void IOCompletionCallback(uint errorCode, // Error code @@ -1392,55 +1341,34 @@ namespace System.Threading NativeOverlapped* pOVERLAP // ptr to OVERLAP structure ); - [HostProtection(Synchronization=true, ExternalThreading=true)] public static class ThreadPool { - #if FEATURE_CORECLR - [System.Security.SecurityCritical] // auto-generated - #else - [System.Security.SecuritySafeCritical] - #endif -#pragma warning disable 618 - [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] -#pragma warning restore 618 public static bool SetMaxThreads(int workerThreads, int completionPortThreads) { return SetMaxThreadsNative(workerThreads, completionPortThreads); } - [System.Security.SecuritySafeCritical] // auto-generated public static void GetMaxThreads(out int workerThreads, out int completionPortThreads) { GetMaxThreadsNative(out workerThreads, out completionPortThreads); } - #if FEATURE_CORECLR - [System.Security.SecurityCritical] // auto-generated - #else - [System.Security.SecuritySafeCritical] - #endif -#pragma warning disable 618 - [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] -#pragma warning restore 618 public static bool SetMinThreads(int workerThreads, int completionPortThreads) { return SetMinThreadsNative(workerThreads, completionPortThreads); } - [System.Security.SecuritySafeCritical] // auto-generated public static void GetMinThreads(out int workerThreads, out int completionPortThreads) { GetMinThreadsNative(out workerThreads, out completionPortThreads); } - [System.Security.SecuritySafeCritical] // auto-generated public static void GetAvailableThreads(out int workerThreads, out int completionPortThreads) { GetAvailableThreadsNative(out workerThreads, out completionPortThreads); } - [System.Security.SecuritySafeCritical] // auto-generated [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException @@ -1455,7 +1383,6 @@ namespace System.Threading return RegisterWaitForSingleObject(waitObject,callBack,state,millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true); } - [System.Security.SecurityCritical] // auto-generated_required [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException @@ -1471,7 +1398,6 @@ namespace System.Threading } - [System.Security.SecurityCritical] // auto-generated private static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException WaitHandle waitObject, WaitOrTimerCallback callBack, @@ -1482,12 +1408,6 @@ namespace System.Threading bool compressStack ) { -#if FEATURE_REMOTING - if (RemotingServices.IsTransparentProxy(waitObject)) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy")); - Contract.EndContractBlock(); -#endif - RegisteredWaitHandle registeredWaitHandle = new RegisteredWaitHandle(); if (callBack != null) @@ -1508,13 +1428,12 @@ namespace System.Threading } else { - throw new ArgumentNullException("WaitOrTimerCallback"); + throw new ArgumentNullException(nameof(WaitOrTimerCallback)); } return registeredWaitHandle; } - [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException WaitHandle waitObject, @@ -1525,13 +1444,12 @@ namespace System.Threading ) { if (millisecondsTimeOutInterval < -1) - throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true); } - [System.Security.SecurityCritical] // auto-generated_required [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException WaitHandle waitObject, @@ -1542,13 +1460,12 @@ namespace System.Threading ) { if (millisecondsTimeOutInterval < -1) - throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false); } - [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException WaitHandle waitObject, @@ -1559,13 +1476,12 @@ namespace System.Threading ) { if (millisecondsTimeOutInterval < -1) - throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true); } - [System.Security.SecurityCritical] // auto-generated_required [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException WaitHandle waitObject, @@ -1576,13 +1492,12 @@ namespace System.Threading ) { if (millisecondsTimeOutInterval < -1) - throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false); } - [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, @@ -1594,14 +1509,13 @@ namespace System.Threading { long tm = (long)timeout.TotalMilliseconds; if (tm < -1) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal")); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,true); } - [System.Security.SecurityCritical] // auto-generated_required [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, @@ -1613,14 +1527,13 @@ namespace System.Threading { long tm = (long)timeout.TotalMilliseconds; if (tm < -1) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal")); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,false); } - [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static bool QueueUserWorkItem( WaitCallback callBack, // NOTE: we do not expose options that allow the callback to be queued as an APC @@ -1631,7 +1544,6 @@ namespace System.Threading return QueueUserWorkItemHelper(callBack,state,ref stackMark,true); } - [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static bool QueueUserWorkItem( WaitCallback callBack // NOTE: we do not expose options that allow the callback to be queued as an APC @@ -1641,7 +1553,6 @@ namespace System.Threading return QueueUserWorkItemHelper(callBack,null,ref stackMark,true); } - [System.Security.SecurityCritical] // auto-generated_required [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static bool UnsafeQueueUserWorkItem( WaitCallback callBack, // NOTE: we do not expose options that allow the callback to be queued as an APC @@ -1655,7 +1566,6 @@ namespace System.Threading //ThreadPool has per-appdomain managed queue of work-items. The VM is //responsible for just scheduling threads into appdomains. After that //work-items are dispatched from the managed queue. - [System.Security.SecurityCritical] // auto-generated private static bool QueueUserWorkItemHelper(WaitCallback callBack, Object state, ref StackCrawlMark stackMark, bool compressStack ) { bool success = true; @@ -1690,15 +1600,14 @@ namespace System.Threading } else { - throw new ArgumentNullException("WaitCallback"); + throw new ArgumentNullException(nameof(WaitCallback)); } return success; } - [SecurityCritical] internal static void UnsafeQueueCustomWorkItem(IThreadPoolWorkItem workItem, bool forceGlobal) { - Contract.Assert(null != workItem); + Debug.Assert(null != workItem); EnsureVMInitialized(); // @@ -1712,17 +1621,15 @@ namespace System.Threading } // This method tries to take the target callback out of the current thread's queue. - [SecurityCritical] internal static bool TryPopCustomWorkItem(IThreadPoolWorkItem workItem) { - Contract.Assert(null != workItem); + Debug.Assert(null != workItem); if (!ThreadPoolGlobals.vmTpInitialized) return false; //Not initialized, so there's no way this workitem was ever queued. return ThreadPoolGlobals.workQueue.LocalFindAndPop(workItem); } // Get all workitems. Called by TaskScheduler in its debugger hooks. - [SecurityCritical] internal static IEnumerable<IThreadPoolWorkItem> GetQueuedWorkItems() { return EnumerateQueuedWorkItems(ThreadPoolWorkQueue.allThreadQueues.Current, ThreadPoolGlobals.workQueue.queueTail); @@ -1766,13 +1673,11 @@ namespace System.Threading } } - [SecurityCritical] internal static IEnumerable<IThreadPoolWorkItem> GetLocallyQueuedWorkItems() { return EnumerateQueuedWorkItems(new ThreadPoolWorkQueue.WorkStealingQueue[] { ThreadPoolWorkQueueThreadLocals.threadLocals.workStealingQueue }, null); } - [SecurityCritical] internal static IEnumerable<IThreadPoolWorkItem> GetGloballyQueuedWorkItems() { return EnumerateQueuedWorkItems(null, ThreadPoolGlobals.workQueue.queueTail); @@ -1800,41 +1705,34 @@ namespace System.Threading // This is the method the debugger will actually call, if it ends up calling // into ThreadPool directly. Tests can use this to simulate a debugger, as well. - [SecurityCritical] internal static object[] GetQueuedWorkItemsForDebugger() { return ToObjectArray(GetQueuedWorkItems()); } - [SecurityCritical] internal static object[] GetGloballyQueuedWorkItemsForDebugger() { return ToObjectArray(GetGloballyQueuedWorkItems()); } - [SecurityCritical] internal static object[] GetLocallyQueuedWorkItemsForDebugger() { return ToObjectArray(GetLocallyQueuedWorkItems()); } - [System.Security.SecurityCritical] // auto-generated [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] internal static extern bool RequestWorkerThread(); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] unsafe private static extern bool PostQueuedCompletionStatus(NativeOverlapped* overlapped); - [System.Security.SecurityCritical] // auto-generated_required [CLSCompliant(false)] unsafe public static bool UnsafeQueueNativeOverlapped(NativeOverlapped* overlapped) { return PostQueuedCompletionStatus(overlapped); } - [SecurityCritical] private static void EnsureVMInitialized() { if (!ThreadPoolGlobals.vmTpInitialized) @@ -1846,35 +1744,27 @@ namespace System.Threading // Native methods: - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool SetMinThreadsNative(int workerThreads, int completionPortThreads); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool SetMaxThreadsNative(int workerThreads, int completionPortThreads); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetMinThreadsNative(out int workerThreads, out int completionPortThreads); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetMaxThreadsNative(out int workerThreads, out int completionPortThreads); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetAvailableThreadsNative(out int workerThreads, out int completionPortThreads); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool NotifyWorkItemComplete(); - [System.Security.SecurityCritical] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void ReportThreadStatus(bool isWorking); - [System.Security.SecuritySafeCritical] internal static void NotifyWorkItemProgress() { if (!ThreadPoolGlobals.vmTpInitialized) @@ -1882,20 +1772,16 @@ namespace System.Threading NotifyWorkItemProgressNative(); } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void NotifyWorkItemProgressNative(); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool IsThreadPoolHosted(); - [System.Security.SecurityCritical] // auto-generated [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void InitializeVMTp(ref bool enableWorkerTracking); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern IntPtr RegisterWaitForSingleObjectNative( WaitHandle waitHandle, @@ -1907,30 +1793,19 @@ namespace System.Threading bool compressStack ); -#if !FEATURE_CORECLR - [System.Security.SecuritySafeCritical] // auto-generated + [Obsolete("ThreadPool.BindHandle(IntPtr) has been deprecated. Please use ThreadPool.BindHandle(SafeHandle) instead.", false)] - [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public static bool BindHandle( IntPtr osHandle ) { return BindIOCompletionCallbackNative(osHandle); } -#endif - #if FEATURE_CORECLR - [System.Security.SecurityCritical] // auto-generated - #else - [System.Security.SecuritySafeCritical] - #endif -#pragma warning disable 618 - [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] -#pragma warning restore 618 public static bool BindHandle(SafeHandle osHandle) { if (osHandle == null) - throw new ArgumentNullException("osHandle"); + throw new ArgumentNullException(nameof(osHandle)); bool ret = false; bool mustReleaseSafeHandle = false; @@ -1946,7 +1821,6 @@ namespace System.Threading return ret; } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private static extern bool BindIOCompletionCallbackNative(IntPtr fileHandle); diff --git a/src/mscorlib/src/System/Threading/Timer.cs b/src/mscorlib/src/System/Threading/Timer.cs index cb08c6e033..5bfefccad2 100644 --- a/src/mscorlib/src/System/Threading/Timer.cs +++ b/src/mscorlib/src/System/Threading/Timer.cs @@ -14,6 +14,7 @@ namespace System.Threading using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution; using System.Runtime.Versioning; + using System.Diagnostics; using System.Diagnostics.Contracts; using System.Diagnostics.Tracing; using Microsoft.Win32.SafeHandles; @@ -76,7 +77,6 @@ namespace System.Threading // private static int TickCount { - [SecuritySafeCritical] get { #if !FEATURE_PAL @@ -102,7 +102,6 @@ namespace System.Threading // // We use a SafeHandle to ensure that the native timer is destroyed when the AppDomain is unloaded. // - [SecurityCritical] class AppDomainTimerSafeHandle : SafeHandleZeroOrMinusOneIsInvalid { public AppDomainTimerSafeHandle() @@ -110,7 +109,6 @@ namespace System.Threading { } - [SecurityCritical] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] protected override bool ReleaseHandle() { @@ -118,14 +116,12 @@ namespace System.Threading } } - [SecurityCritical] AppDomainTimerSafeHandle m_appDomainTimer; bool m_isAppDomainTimerScheduled; int m_currentAppDomainTimerStartTicks; uint m_currentAppDomainTimerDuration; - [SecuritySafeCritical] private bool EnsureAppDomainTimerFiresBy(uint requestedDuration) { // @@ -154,14 +150,14 @@ namespace System.Threading // A later update during resume will re-schedule if(m_pauseTicks != 0) { - Contract.Assert(!m_isAppDomainTimerScheduled); - Contract.Assert(m_appDomainTimer == null); + Debug.Assert(!m_isAppDomainTimerScheduled); + Debug.Assert(m_appDomainTimer == null); return true; } if (m_appDomainTimer == null || m_appDomainTimer.IsInvalid) { - Contract.Assert(!m_isAppDomainTimerScheduled); + Debug.Assert(!m_isAppDomainTimerScheduled); m_appDomainTimer = CreateAppDomainTimer(actualDuration); if (!m_appDomainTimer.IsInvalid) @@ -195,23 +191,19 @@ namespace System.Threading // // The VM calls this when the native timer fires. // - [SecuritySafeCritical] internal static void AppDomainTimerCallback() { Instance.FireNextTimers(); } - [System.Security.SecurityCritical] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] static extern AppDomainTimerSafeHandle CreateAppDomainTimer(uint dueTime); - [System.Security.SecurityCritical] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] static extern bool ChangeAppDomainTimer(AppDomainTimerSafeHandle handle, uint dueTime); - [System.Security.SecurityCritical] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] @@ -229,7 +221,6 @@ namespace System.Threading volatile int m_pauseTicks = 0; // Time when Pause was called - [SecurityCritical] internal void Pause() { lock(this) @@ -245,7 +236,6 @@ namespace System.Threading } } - [SecurityCritical] internal void Resume() { // @@ -269,8 +259,8 @@ namespace System.Threading TimerQueueTimer timer = m_timers; while (timer != null) { - Contract.Assert(timer.m_dueTime != Timeout.UnsignedInfinite); - Contract.Assert(resumedTicks >= timer.m_startTicks); + Debug.Assert(timer.m_dueTime != Timeout.UnsignedInfinite); + Debug.Assert(resumedTicks >= timer.m_startTicks); uint elapsed; // How much of the timer dueTime has already elapsed @@ -343,7 +333,7 @@ namespace System.Threading TimerQueueTimer timer = m_timers; while (timer != null) { - Contract.Assert(timer.m_dueTime != Timeout.UnsignedInfinite); + Debug.Assert(timer.m_dueTime != Timeout.UnsignedInfinite); uint elapsed = (uint)(nowTicks - timer.m_startTicks); if (elapsed >= timer.m_dueTime) @@ -413,7 +403,6 @@ namespace System.Threading timerToFireOnThisThread.Fire(); } - [SecuritySafeCritical] private static void QueueTimerCompletion(TimerQueueTimer timer) { WaitCallback callback = s_fireQueuedTimerCompletion; @@ -523,7 +512,6 @@ namespace System.Threading volatile WaitHandle m_notifyWhenNoCallbacksRunning; - [SecurityCritical] internal TimerQueueTimer(TimerCallback timerCallback, object state, uint dueTime, uint period, ref StackCrawlMark stackMark) { m_timerCallback = timerCallback; @@ -673,13 +661,11 @@ namespace System.Threading SignalNoCallbacksRunning(); } - [SecuritySafeCritical] internal void SignalNoCallbacksRunning() { Win32Native.SetEvent(m_notifyWhenNoCallbacksRunning.SafeWaitHandle); } - [SecuritySafeCritical] internal void CallCallback() { if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer)) @@ -708,10 +694,8 @@ namespace System.Threading } } - [SecurityCritical] private static ContextCallback s_callCallbackInContext; - [SecurityCritical] private static void CallCallbackInContext(object state) { TimerQueueTimer t = (TimerQueueTimer)state; @@ -772,19 +756,13 @@ namespace System.Threading } - [HostProtection(Synchronization=true, ExternalThreading=true)] [System.Runtime.InteropServices.ComVisible(true)] -#if FEATURE_REMOTING public sealed class Timer : MarshalByRefObject, IDisposable -#else // FEATURE_REMOTING - public sealed class Timer : IDisposable -#endif // FEATURE_REMOTING { private const UInt32 MAX_SUPPORTED_TIMEOUT = (uint)0xfffffffe; private TimerHolder m_timer; - [SecuritySafeCritical] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public Timer(TimerCallback callback, Object state, @@ -792,16 +770,15 @@ namespace System.Threading int period) { if (dueTime < -1) - throw new ArgumentOutOfRangeException("dueTime", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(dueTime), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (period < -1 ) - throw new ArgumentOutOfRangeException("period", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(period), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; TimerSetup(callback,state,(UInt32)dueTime,(UInt32)period,ref stackMark); } - [SecuritySafeCritical] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public Timer(TimerCallback callback, Object state, @@ -810,22 +787,21 @@ namespace System.Threading { long dueTm = (long)dueTime.TotalMilliseconds; if (dueTm < -1) - throw new ArgumentOutOfRangeException("dueTm",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(dueTm),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (dueTm > MAX_SUPPORTED_TIMEOUT) - throw new ArgumentOutOfRangeException("dueTm",Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge")); + throw new ArgumentOutOfRangeException(nameof(dueTm),Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge")); long periodTm = (long)period.TotalMilliseconds; if (periodTm < -1) - throw new ArgumentOutOfRangeException("periodTm",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(periodTm),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (periodTm > MAX_SUPPORTED_TIMEOUT) - throw new ArgumentOutOfRangeException("periodTm",Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge")); + throw new ArgumentOutOfRangeException(nameof(periodTm),Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge")); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; TimerSetup(callback,state,(UInt32)dueTm,(UInt32)periodTm,ref stackMark); } [CLSCompliant(false)] - [SecuritySafeCritical] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public Timer(TimerCallback callback, Object state, @@ -836,7 +812,6 @@ namespace System.Threading TimerSetup(callback,state,dueTime,period,ref stackMark); } - [SecuritySafeCritical] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public Timer(TimerCallback callback, Object state, @@ -844,19 +819,18 @@ namespace System.Threading long period) { if (dueTime < -1) - throw new ArgumentOutOfRangeException("dueTime",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(dueTime),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (period < -1) - throw new ArgumentOutOfRangeException("period",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(period),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (dueTime > MAX_SUPPORTED_TIMEOUT) - throw new ArgumentOutOfRangeException("dueTime",Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge")); + throw new ArgumentOutOfRangeException(nameof(dueTime),Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge")); if (period > MAX_SUPPORTED_TIMEOUT) - throw new ArgumentOutOfRangeException("period",Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge")); + throw new ArgumentOutOfRangeException(nameof(period),Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge")); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; TimerSetup(callback,state,(UInt32) dueTime, (UInt32) period,ref stackMark); } - [SecuritySafeCritical] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public Timer(TimerCallback callback) { @@ -869,7 +843,6 @@ namespace System.Threading TimerSetup(callback, this, (UInt32)dueTime, (UInt32)period, ref stackMark); } - [SecurityCritical] private void TimerSetup(TimerCallback callback, Object state, UInt32 dueTime, @@ -877,19 +850,17 @@ namespace System.Threading ref StackCrawlMark stackMark) { if (callback == null) - throw new ArgumentNullException("TimerCallback"); + throw new ArgumentNullException(nameof(TimerCallback)); Contract.EndContractBlock(); m_timer = new TimerHolder(new TimerQueueTimer(callback, state, dueTime, period, ref stackMark)); } - [SecurityCritical] internal static void Pause() { TimerQueue.Instance.Pause(); } - [SecurityCritical] internal static void Resume() { TimerQueue.Instance.Resume(); @@ -898,9 +869,9 @@ namespace System.Threading public bool Change(int dueTime, int period) { if (dueTime < -1 ) - throw new ArgumentOutOfRangeException("dueTime",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(dueTime),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (period < -1) - throw new ArgumentOutOfRangeException("period",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(period),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); Contract.EndContractBlock(); return m_timer.m_timer.Change((UInt32)dueTime, (UInt32)period); @@ -920,13 +891,13 @@ namespace System.Threading public bool Change(long dueTime, long period) { if (dueTime < -1 ) - throw new ArgumentOutOfRangeException("dueTime", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(dueTime), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (period < -1) - throw new ArgumentOutOfRangeException("period", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(period), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (dueTime > MAX_SUPPORTED_TIMEOUT) - throw new ArgumentOutOfRangeException("dueTime", Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge")); + throw new ArgumentOutOfRangeException(nameof(dueTime), Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge")); if (period > MAX_SUPPORTED_TIMEOUT) - throw new ArgumentOutOfRangeException("period", Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge")); + throw new ArgumentOutOfRangeException(nameof(period), Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge")); Contract.EndContractBlock(); return m_timer.m_timer.Change((UInt32)dueTime, (UInt32)period); @@ -935,7 +906,7 @@ namespace System.Threading public bool Dispose(WaitHandle notifyObject) { if (notifyObject==null) - throw new ArgumentNullException("notifyObject"); + throw new ArgumentNullException(nameof(notifyObject)); Contract.EndContractBlock(); return m_timer.Close(notifyObject); diff --git a/src/mscorlib/src/System/Threading/Volatile.cs b/src/mscorlib/src/System/Threading/Volatile.cs index af687fbae1..3894b435fa 100644 --- a/src/mscorlib/src/System/Threading/Volatile.cs +++ b/src/mscorlib/src/System/Threading/Volatile.cs @@ -129,7 +129,6 @@ namespace System.Threading [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [CLSCompliant(false)] [System.Runtime.Versioning.NonVersionable] - [SecuritySafeCritical] // to match 32-bit version public static ulong Read(ref ulong location) { // @@ -154,7 +153,6 @@ namespace System.Threading [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [CLSCompliant(false)] - [SecuritySafeCritical] // contains unsafe code public static ulong Read(ref ulong location) { unsafe @@ -222,7 +220,6 @@ namespace System.Threading } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [SecuritySafeCritical] //the intrinsic implementation of this method contains unverifiable code [System.Runtime.Versioning.NonVersionable] public static T Read<T>(ref T location) where T : class { @@ -332,7 +329,6 @@ namespace System.Threading [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [CLSCompliant(false)] [System.Runtime.Versioning.NonVersionable] - [SecuritySafeCritical] // to match 32-bit version public static void Write(ref ulong location, ulong value) { // @@ -356,7 +352,6 @@ namespace System.Threading [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [CLSCompliant(false)] - [SecuritySafeCritical] // contains unsafe code public static void Write(ref ulong location, ulong value) { // @@ -427,7 +422,6 @@ namespace System.Threading } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [SecuritySafeCritical] //the intrinsic implementation of this method contains unverifiable code [System.Runtime.Versioning.NonVersionable] public static void Write<T>(ref T location, T value) where T : class { diff --git a/src/mscorlib/src/System/Threading/WaitHandle.cs b/src/mscorlib/src/System/Threading/WaitHandle.cs index 9980c822a6..7638c8b35b 100644 --- a/src/mscorlib/src/System/Threading/WaitHandle.cs +++ b/src/mscorlib/src/System/Threading/WaitHandle.cs @@ -27,12 +27,8 @@ namespace System.Threading using System.Diagnostics.CodeAnalysis; using Win32Native = Microsoft.Win32.Win32Native; -[System.Runtime.InteropServices.ComVisible(true)] -#if FEATURE_REMOTING + [System.Runtime.InteropServices.ComVisible(true)] public abstract class WaitHandle : MarshalByRefObject, IDisposable { -#else // FEATURE_REMOTING - public abstract class WaitHandle : IDisposable { -#endif // FEATURE_REMOTING public const int WaitTimeout = 0x102; private const int MAX_WAITHANDLES = 64; @@ -41,12 +37,10 @@ namespace System.Threading private IntPtr waitHandle; // !!! DO NOT MOVE THIS FIELD. (See defn of WAITHANDLEREF in object.h - has hardcoded access to this field.) #pragma warning restore 414 - [System.Security.SecurityCritical] // auto-generated internal volatile SafeWaitHandle safeWaitHandle; internal bool hasThreadAffinity; - [System.Security.SecuritySafeCritical] // auto-generated private static IntPtr GetInvalidHandle() { return Win32Native.INVALID_HANDLE_VALUE; @@ -70,7 +64,6 @@ namespace System.Threading Init(); } - [System.Security.SecuritySafeCritical] // auto-generated private void Init() { safeWaitHandle = null; @@ -82,13 +75,7 @@ namespace System.Threading [Obsolete("Use the SafeWaitHandle property instead.")] public virtual IntPtr Handle { - [System.Security.SecuritySafeCritical] // auto-generated get { return safeWaitHandle == null ? InvalidHandle : safeWaitHandle.DangerousGetHandle();} - - [System.Security.SecurityCritical] // auto-generated_required -#if !FEATURE_CORECLR - [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] -#endif set { if (value == InvalidHandle) @@ -113,13 +100,8 @@ namespace System.Threading } } - public SafeWaitHandle SafeWaitHandle { - [System.Security.SecurityCritical] // auto-generated_required -#if !FEATURE_CORECLR - [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] -#endif [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] get { @@ -129,11 +111,7 @@ namespace System.Threading } return safeWaitHandle; } - - [System.Security.SecurityCritical] // auto-generated_required -#if !FEATURE_CORECLR - [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] -#endif + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] set { @@ -168,7 +146,6 @@ namespace System.Threading // FileStream, which will then call Sethandle, which requires a link time // security check.). While security has fixed that problem, we still // don't need to do a linktime check here. - [System.Security.SecurityCritical] // auto-generated internal void SetHandleInternal(SafeWaitHandle handle) { safeWaitHandle = handle; @@ -179,7 +156,7 @@ namespace System.Threading { if (millisecondsTimeout < -1) { - throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } Contract.EndContractBlock(); return WaitOne((long)millisecondsTimeout,exitContext); @@ -190,7 +167,7 @@ namespace System.Threading long tm = (long)timeout.TotalMilliseconds; if (-1 > tm || (long) Int32.MaxValue < tm) { - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } return WaitOne(tm,exitContext); } @@ -211,14 +188,12 @@ namespace System.Threading return WaitOne(timeout, false); } - [System.Security.SecuritySafeCritical] // auto-generated [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety.")] private bool WaitOne(long timeout, bool exitContext) { return InternalWaitOne(safeWaitHandle, timeout, hasThreadAffinity, exitContext); } - [System.Security.SecurityCritical] // auto-generated internal static bool InternalWaitOne(SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext) { if (waitableSafeHandle == null) @@ -238,7 +213,6 @@ namespace System.Threading return (ret != WaitTimeout); } - [System.Security.SecurityCritical] internal bool WaitOneWithoutFAS() { // version of waitone without fast application switch (FAS) support @@ -258,7 +232,6 @@ namespace System.Threading return (ret != WaitTimeout); } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern int WaitOneNative(SafeHandle waitableSafeHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext); @@ -271,17 +244,15 @@ namespace System.Threading ** (if in a synchronized context) is exited before the wait and reacquired ========================================================================*/ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private static extern int WaitMultiple(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext, bool WaitAll); - [System.Security.SecuritySafeCritical] // auto-generated public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) { if (waitHandles == null) { - throw new ArgumentNullException("waitHandles", Environment.GetResourceString("ArgumentNull_Waithandles")); + throw new ArgumentNullException(nameof(waitHandles), Environment.GetResourceString("ArgumentNull_Waithandles")); } if(waitHandles.Length == 0) { @@ -294,11 +265,7 @@ namespace System.Threading // in CoreCLR, and ArgumentNullException in the desktop CLR. This is ugly, but so is breaking // user code. // -#if FEATURE_CORECLR throw new ArgumentException(Environment.GetResourceString("Argument_EmptyWaithandleArray")); -#else - throw new ArgumentNullException("waitHandles", Environment.GetResourceString("Argument_EmptyWaithandleArray")); -#endif } if (waitHandles.Length > MAX_WAITHANDLES) { @@ -306,7 +273,7 @@ namespace System.Threading } if (-1 > millisecondsTimeout) { - throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } Contract.EndContractBlock(); WaitHandle[] internalWaitHandles = new WaitHandle[waitHandles.Length]; @@ -317,11 +284,6 @@ namespace System.Threading if (waitHandle == null) throw new ArgumentNullException("waitHandles[" + i + "]", Environment.GetResourceString("ArgumentNull_ArrayElement")); -#if FEATURE_REMOTING - if (RemotingServices.IsTransparentProxy(waitHandle)) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy")); -#endif - internalWaitHandles[i] = waitHandle; } #if _DEBUG @@ -354,7 +316,7 @@ namespace System.Threading long tm = (long)timeout.TotalMilliseconds; if (-1 > tm || (long) Int32.MaxValue < tm) { - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } return WaitAll(waitHandles,(int)tm, exitContext); } @@ -388,13 +350,12 @@ namespace System.Threading ** (if in a synchronized context) is exited before the wait and reacquired ========================================================================*/ - [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) { if (waitHandles==null) { - throw new ArgumentNullException("waitHandles", Environment.GetResourceString("ArgumentNull_Waithandles")); + throw new ArgumentNullException(nameof(waitHandles), Environment.GetResourceString("ArgumentNull_Waithandles")); } if(waitHandles.Length == 0) { @@ -406,7 +367,7 @@ namespace System.Threading } if (-1 > millisecondsTimeout) { - throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } Contract.EndContractBlock(); WaitHandle[] internalWaitHandles = new WaitHandle[waitHandles.Length]; @@ -417,11 +378,6 @@ namespace System.Threading if (waitHandle == null) throw new ArgumentNullException("waitHandles[" + i + "]", Environment.GetResourceString("ArgumentNull_ArrayElement")); -#if FEATURE_REMOTING - if (RemotingServices.IsTransparentProxy(waitHandle)) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy")); -#endif - internalWaitHandles[i] = waitHandle; } #if _DEBUG @@ -459,7 +415,7 @@ namespace System.Threading long tm = (long)timeout.TotalMilliseconds; if (-1 > tm || (long) Int32.MaxValue < tm) { - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } return WaitAny(waitHandles,(int)tm, exitContext); } @@ -491,7 +447,6 @@ namespace System.Threading == ==================================================*/ - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern int SignalAndWaitOne(SafeWaitHandle waitHandleToSignal,SafeWaitHandle waitHandleToWaitOn, int millisecondsTimeout, bool hasThreadAffinity, bool exitContext); @@ -519,13 +474,12 @@ namespace System.Threading long tm = (long)timeout.TotalMilliseconds; if (-1 > tm || (long) Int32.MaxValue < tm) { - throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } return SignalAndWait(toSignal,toWaitOn,(int)tm,exitContext); #endif } - [System.Security.SecuritySafeCritical] // auto-generated [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety.")] public static bool SignalAndWait( WaitHandle toSignal, @@ -538,15 +492,15 @@ namespace System.Threading #else if(null == toSignal) { - throw new ArgumentNullException("toSignal"); + throw new ArgumentNullException(nameof(toSignal)); } if(null == toWaitOn) { - throw new ArgumentNullException("toWaitOn"); + throw new ArgumentNullException(nameof(toWaitOn)); } if (-1 > millisecondsTimeout) { - throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } Contract.EndContractBlock(); @@ -554,14 +508,6 @@ namespace System.Threading int ret = SignalAndWaitOne(toSignal.safeWaitHandle,toWaitOn.safeWaitHandle,millisecondsTimeout, toWaitOn.hasThreadAffinity,exitContext); -#if !FEATURE_CORECLR - if(WAIT_FAILED != ret && toSignal.hasThreadAffinity) - { - Thread.EndCriticalRegion(); - Thread.EndThreadAffinity(); - } -#endif - if(WAIT_ABANDONED == ret) { ThrowAbandonedMutexException(); @@ -599,7 +545,6 @@ namespace System.Threading GC.SuppressFinalize(this); } - [System.Security.SecuritySafeCritical] // auto-generated protected virtual void Dispose(bool explicitDisposing) { if (safeWaitHandle != null) diff --git a/src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs b/src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs index f873057992..68445a78d9 100644 --- a/src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs +++ b/src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs @@ -12,11 +12,7 @@ namespace System.Threading [Serializable] [ComVisibleAttribute(false)] -#if FEATURE_CORECLR - public class WaitHandleCannotBeOpenedException : Exception { -#else public class WaitHandleCannotBeOpenedException : ApplicationException { -#endif // FEATURE_CORECLR public WaitHandleCannotBeOpenedException() : base(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException")) { SetErrorCode(__HResults.COR_E_WAITHANDLECANNOTBEOPENED); diff --git a/src/mscorlib/src/System/Threading/WaitHandleExtensions.cs b/src/mscorlib/src/System/Threading/WaitHandleExtensions.cs deleted file mode 100644 index 76c3feb649..0000000000 --- a/src/mscorlib/src/System/Threading/WaitHandleExtensions.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// - -using Microsoft.Win32.SafeHandles; -using System.Security; - -namespace System.Threading -{ - public static class WaitHandleExtensions - { - /// <summary> - /// Gets the native operating system handle. - /// </summary> - /// <param name="waitHandle">The <see cref="System.Threading.WaitHandle"/> to operate on.</param> - /// <returns>A <see cref="System.Runtime.InteropServices.SafeHandle"/> representing the native operating system handle.</returns> - [SecurityCritical] - public static SafeWaitHandle GetSafeWaitHandle(this WaitHandle waitHandle) - { - if (waitHandle == null) - { - throw new ArgumentNullException("waitHandle"); - } - - return waitHandle.SafeWaitHandle; - } - - /// <summary> - /// Sets the native operating system handle - /// </summary> - /// <param name="waitHandle">The <see cref="System.Threading.WaitHandle"/> to operate on.</param> - /// <param name="value">A <see cref="System.Runtime.InteropServices.SafeHandle"/> representing the native operating system handle.</param> - [SecurityCritical] - public static void SetSafeWaitHandle(this WaitHandle waitHandle, SafeWaitHandle value) - { - if (waitHandle == null) - { - throw new ArgumentNullException("waitHandle"); - } - - waitHandle.SafeWaitHandle = value; - } - } -} |