summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Threading
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Threading')
-rw-r--r--src/mscorlib/src/System/Threading/AsyncLocal.cs387
-rw-r--r--src/mscorlib/src/System/Threading/AutoResetEvent.cs1
-rw-r--r--src/mscorlib/src/System/Threading/CancellationToken.cs14
-rw-r--r--src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs1
-rw-r--r--src/mscorlib/src/System/Threading/CancellationTokenSource.cs37
-rw-r--r--src/mscorlib/src/System/Threading/CountdownEvent.cs23
-rw-r--r--src/mscorlib/src/System/Threading/EventWaitHandle.cs69
-rw-r--r--src/mscorlib/src/System/Threading/ExecutionContext.cs1222
-rw-r--r--src/mscorlib/src/System/Threading/Interlocked.cs17
-rw-r--r--src/mscorlib/src/System/Threading/LazyInitializer.cs4
-rw-r--r--src/mscorlib/src/System/Threading/LockRecursionException.cs3
-rw-r--r--src/mscorlib/src/System/Threading/ManualResetEvent.cs1
-rw-r--r--src/mscorlib/src/System/Threading/ManualResetEventSlim.cs33
-rw-r--r--src/mscorlib/src/System/Threading/Monitor.cs26
-rw-r--r--src/mscorlib/src/System/Threading/Mutex.cs208
-rw-r--r--src/mscorlib/src/System/Threading/Overlapped.cs42
-rw-r--r--src/mscorlib/src/System/Threading/ReaderWriterLock.cs36
-rw-r--r--src/mscorlib/src/System/Threading/Semaphore.cs35
-rw-r--r--src/mscorlib/src/System/Threading/SemaphoreFullException.cs3
-rw-r--r--src/mscorlib/src/System/Threading/SemaphoreSlim.cs50
-rw-r--r--src/mscorlib/src/System/Threading/SpinLock.cs110
-rw-r--r--src/mscorlib/src/System/Threading/SpinWait.cs18
-rw-r--r--src/mscorlib/src/System/Threading/SynchronizationContext.cs90
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs4
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs16
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs42
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs148
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/Parallel.cs229
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs7
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs9
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs12
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs12
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/Task.cs229
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs6
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs64
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs36
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs100
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs21
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs5
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs7
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/future.cs27
-rw-r--r--src/mscorlib/src/System/Threading/Thread.cs633
-rw-r--r--src/mscorlib/src/System/Threading/ThreadAbortException.cs1
-rw-r--r--src/mscorlib/src/System/Threading/ThreadLocal.cs17
-rw-r--r--src/mscorlib/src/System/Threading/ThreadPool.cs230
-rw-r--r--src/mscorlib/src/System/Threading/Timer.cs79
-rw-r--r--src/mscorlib/src/System/Threading/Volatile.cs6
-rw-r--r--src/mscorlib/src/System/Threading/WaitHandle.cs83
-rw-r--r--src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs4
-rw-r--r--src/mscorlib/src/System/Threading/WaitHandleExtensions.cs46
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;
- }
- }
-}