summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoundinya Veluri <kouvel@microsoft.com>2016-11-06 19:25:29 -0800
committerKoundinya Veluri <kouvel@microsoft.com>2016-11-10 19:51:33 -0800
commit9c1550e443a73cd072608ea18f846f16441b4db3 (patch)
tree1760f8aa1851d1fcaedbb7ebc7c02971c83854ad
parent1b0dad67bc88bd4a45f59e63c6bf9fd5e7eb8596 (diff)
downloadcoreclr-9c1550e443a73cd072608ea18f846f16441b4db3.tar.gz
coreclr-9c1550e443a73cd072608ea18f846f16441b4db3.tar.bz2
coreclr-9c1550e443a73cd072608ea18f846f16441b4db3.zip
Expose some things for ns2.0
Mostly: - Exposed flow-related methods on `ExecutionContext` - Enabled and exposed `SynchronizationContext` wait overriding Realted issues: - dotnet/corefx#11638 - dotnet/corefx#11633 - dotnet/corefx#11635 - dotnet/corefx#11636 - dotnet/corefx#13484
-rw-r--r--clr.coreclr.props1
-rw-r--r--clr.defines.targets1
-rw-r--r--clrdefinitions.cmake1
-rw-r--r--src/mscorlib/model.xml47
-rw-r--r--src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs38
-rw-r--r--src/mscorlib/src/System/Threading/ExecutionContext.cs177
-rw-r--r--src/mscorlib/src/System/Threading/Thread.cs10
-rw-r--r--src/vm/ecalllist.h8
-rw-r--r--src/vm/object.h19
-rw-r--r--src/vm/threads.h6
10 files changed, 241 insertions, 67 deletions
diff --git a/clr.coreclr.props b/clr.coreclr.props
index 26e21187aa..8ff0f0b263 100644
--- a/clr.coreclr.props
+++ b/clr.coreclr.props
@@ -51,6 +51,7 @@
<FeatureUseAsmGCWriteBarriers>true</FeatureUseAsmGCWriteBarriers>
<!-- Setting this to "false" works only for workstation GC, not server. -->
<FeatureSymDiff>true</FeatureSymDiff>
+ <FeatureSynchronizationContextWait>true</FeatureSynchronizationContextWait>
<FeatureReadyToRun Condition="'$(TargetArch)'!='arm64'">true</FeatureReadyToRun>
<FeatureCoreSystem>true</FeatureCoreSystem>
diff --git a/clr.defines.targets b/clr.defines.targets
index e7b0e86fc1..a45d0dd9de 100644
--- a/clr.defines.targets
+++ b/clr.defines.targets
@@ -98,6 +98,7 @@
<CDefines Condition="'$(FeatureStrongnameDelaySigningAllowed)' == 'true'">$(CDefines);FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED</CDefines>
<CDefines Condition="'$(FeatureStrongnameMigration)' == 'true'">$(CDefines);FEATURE_STRONGNAME_MIGRATION</CDefines>
<CDefines Condition="'$(FeatureSvrGc)' == 'true'">$(CDefines);FEATURE_SVR_GC</CDefines>
+ <CDefines Condition="'$(FeatureSynchronizationContextWait)' == 'true'">$(CDefines);FEATURE_SYNCHRONIZATIONCONTEXT_WAIT</CDefines>
<CDefines Condition="'$(FeaturePerfMap)' == 'true'">$(CDefines);FEATURE_PERFMAP</CDefines>
<CDefines Condition="'$(FeatureSynchronizationcontextWait)' == 'true'">$(CDefines);FEATURE_SYNCHRONIZATIONCONTEXT_WAIT</CDefines>
<CDefines Condition="'$(FeatureSyntheticCultures)' == 'true'">$(CDefines);FEATURE_SYNTHETIC_CULTURES</CDefines>
diff --git a/clrdefinitions.cmake b/clrdefinitions.cmake
index 3803d577ff..99f1ad1a05 100644
--- a/clrdefinitions.cmake
+++ b/clrdefinitions.cmake
@@ -176,6 +176,7 @@ if (CLR_CMAKE_PLATFORM_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64)
endif ()
add_definitions(-DFEATURE_SVR_GC)
add_definitions(-DFEATURE_SYMDIFF)
+add_definitions(-DFEATURE_SYNCHRONIZATIONCONTEXT_WAIT)
add_definitions(-DFEATURE_SYNTHETIC_CULTURES)
if(CLR_CMAKE_PLATFORM_UNIX_AMD64)
add_definitions(-DFEATURE_MULTIREG_RETURN)
diff --git a/src/mscorlib/model.xml b/src/mscorlib/model.xml
index 8d8ff11ace..46bab1e103 100644
--- a/src/mscorlib/model.xml
+++ b/src/mscorlib/model.xml
@@ -8101,14 +8101,18 @@
</Type>
<Type Name="System.Threading.SynchronizationContext">
<Member Name="#ctor"/>
- <Member Name="Send(System.Threading.SendOrPostCallback,System.Object)"/>
- <Member Name="Post(System.Threading.SendOrPostCallback,System.Object)"/>
- <Member Name="OperationStarted"/>
- <Member Name="OperationCompleted"/>
- <Member Name="SetSynchronizationContext(System.Threading.SynchronizationContext)"/>
- <Member Name="get_Current"/>
<Member Name="CreateCopy"/>
<Member MemberType="Property" Name="Current"/>
+ <Member Status="ImplRoot" Name="InvokeWaitMethodHelper(System.Threading.SynchronizationContext,System.IntPtr[],System.Boolean,System.Int32)"/>
+ <Member Name="IsWaitNotificationRequired"/>
+ <Member Name="OperationCompleted"/>
+ <Member Name="OperationStarted"/>
+ <Member Name="Post(System.Threading.SendOrPostCallback,System.Object)"/>
+ <Member Name="Send(System.Threading.SendOrPostCallback,System.Object)"/>
+ <Member Name="SetSynchronizationContext(System.Threading.SynchronizationContext)"/>
+ <Member Name="SetWaitNotificationRequired"/>
+ <Member Name="Wait(System.IntPtr[],System.Boolean,System.Int32)"/>
+ <Member Name="WaitHelper(System.IntPtr[],System.Boolean,System.Int32)"/>
</Type>
<Type Name="System.Threading.SynchronizationLockException">
<Member Name="#ctor" />
@@ -8156,6 +8160,7 @@
<Member Name="Create(System.Threading.ThreadStart,System.Int32)" />
<Member Name="Create(System.Threading.ParameterizedThreadStart)" />
<Member Name="Create(System.Threading.ParameterizedThreadStart,System.Int32)" />
+ <Member Name="DisableComObjectEagerCleanup" />
<Member Name="GetApartmentState" />
<Member Name="Interrupt" />
<Member Name="Join" />
@@ -8171,27 +8176,33 @@
<Member Status="ImplRoot" Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
</Type>
<Type Name="System.Threading.ThreadPool">
+ <Member Name="BindHandle(System.IntPtr)" />
+ <Member Name="BindHandle(System.Runtime.InteropServices.SafeHandle)" />
+ <Member Status="ImplRoot" Name="GetGloballyQueuedWorkItemsForDebugger"/>
+ <Member Status="ImplRoot" Name="GetLocallyQueuedWorkItemsForDebugger"/>
+ <Member Name="GetAvailableThreads(System.Int32@,System.Int32@)" />
<Member Name="GetMaxThreads(System.Int32@,System.Int32@)" />
+ <Member Name="GetMinThreads(System.Int32@,System.Int32@)" />
+ <Member Status="ImplRoot" Name="GetQueuedWorkItemsForDebugger"/>
+ <Member Status="ImplRoot" Name="NotifyWorkItemProgress"/>
<Member Name="QueueUserWorkItem(System.Threading.WaitCallback)" />
<Member Name="QueueUserWorkItem(System.Threading.WaitCallback,System.Object)" />
- <Member Name="SetMaxThreads(System.Int32,System.Int32)" />
- <Member Name="BindHandle(System.IntPtr)" />
- <Member Name="BindHandle(System.Runtime.InteropServices.SafeHandle)" />
- <Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.UInt32,System.Boolean)" />
<Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.Int32,System.Boolean)" />
<Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.Int64,System.Boolean)" />
<Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.TimeSpan,System.Boolean)" />
- <Member Name="SetMinThreads(System.Int32,System.Int32)" />
- <Member Name="GetMinThreads(System.Int32@,System.Int32@)" />
+ <Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.UInt32,System.Boolean)" />
<Member Status="ImplRoot" Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.UInt32,System.Boolean,System.Threading.StackCrawlMark@,System.Boolean)" />
<Member Status="ImplRoot" Name="RegisterWaitForSingleObjectNative(System.Threading.WaitHandle,System.Object,System.UInt32,System.Boolean,System.Threading.RegisteredWaitHandle,System.Threading.StackCrawlMark@,System.Boolean)" />
- <Member Name="UnsafeQueueNativeOverlapped(System.Threading.NativeOverlapped*)" />
- <Member Status="ImplRoot" Name="UnsafeQueueCustomWorkItem(System.Threading.IThreadPoolWorkItem,System.Boolean)"/>
+ <Member Name="SetMaxThreads(System.Int32,System.Int32)" />
+ <Member Name="SetMinThreads(System.Int32,System.Int32)" />
<Member Status="ImplRoot" Name="TryPopCustomWorkItem(System.Threading.IThreadPoolWorkItem)"/>
- <Member Status="ImplRoot" Name="GetQueuedWorkItemsForDebugger"/>
- <Member Status="ImplRoot" Name="GetGloballyQueuedWorkItemsForDebugger"/>
- <Member Status="ImplRoot" Name="GetLocallyQueuedWorkItemsForDebugger"/>
- <Member Status="ImplRoot" Name="NotifyWorkItemProgress"/>
+ <Member Status="ImplRoot" Name="UnsafeQueueCustomWorkItem(System.Threading.IThreadPoolWorkItem,System.Boolean)"/>
+ <Member Name="UnsafeQueueNativeOverlapped(System.Threading.NativeOverlapped*)" />
+ <Member Name="UnsafeQueueUserWorkItem(System.Threading.WaitCallback,System.Object)" />
+ <Member Name="UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.Int32,System.Boolean)" />
+ <Member Name="UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.Int64,System.Boolean)" />
+ <Member Name="UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.TimeSpan,System.Boolean)" />
+ <Member Name="UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.UInt32,System.Boolean)" />
</Type>
<Type Name="System.Threading.ThreadPriority">
<Member MemberType="Field" Name="AboveNormal" />
diff --git a/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs b/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs
index b391badcd1..419ad92024 100644
--- a/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs
+++ b/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs
@@ -54,11 +54,11 @@ namespace Internal.Runtime.Augments
}
[SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
private extern bool IsBackgroundNative();
[SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
private extern void SetBackgroundNative(bool isBackground);
/*=========================================================================
@@ -89,11 +89,11 @@ namespace Internal.Runtime.Augments
}
[SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
private extern int GetPriorityNative();
[SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
private extern void SetPriorityNative(int priority);
/*=========================================================================
@@ -107,10 +107,10 @@ namespace Internal.Runtime.Augments
}
[SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
private extern int GetThreadStateNative();
- [System.Security.SecuritySafeCritical] // auto-generated
+ [SecuritySafeCritical] // auto-generated
public ApartmentState GetApartmentState()
{
#if FEATURE_COMINTEROP_APARTMENT_SUPPORT
@@ -125,7 +125,7 @@ namespace Internal.Runtime.Augments
** An unstarted thread can be marked to indicate that it will host a
** single-threaded or multi-threaded apartment.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
+ [SecuritySafeCritical] // auto-generated
[HostProtection(Synchronization = true, SelfAffectingThreading = true)]
public bool TrySetApartmentState(ApartmentState state)
{
@@ -157,14 +157,28 @@ namespace Internal.Runtime.Augments
}
[SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal extern int GetApartmentStateNative();
[SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch);
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
+#if FEATURE_COMINTEROP
+ [SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public extern void DisableComObjectEagerCleanup();
+#else // !FEATURE_COMINTEROP
+ [SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public void DisableComObjectEagerCleanup()
+ {
+ Contract.Assert(false); // the Thread class in CoreFX should have handled this case
+ }
+#endif // FEATURE_COMINTEROP
+
/*=========================================================================
** 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
@@ -182,8 +196,8 @@ namespace Internal.Runtime.Augments
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [SecurityCritical] // auto-generated
+ [MethodImpl(MethodImplOptions.InternalCall)]
private extern void InterruptInternal();
/*=========================================================================
@@ -204,7 +218,7 @@ namespace Internal.Runtime.Augments
public bool Join(int millisecondsTimeout) => JoinInternal(millisecondsTimeout);
[SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
private extern bool JoinInternal(int millisecondsTimeout);
public static void Sleep(int millisecondsTimeout) => Thread.Sleep(millisecondsTimeout);
diff --git a/src/mscorlib/src/System/Threading/ExecutionContext.cs b/src/mscorlib/src/System/Threading/ExecutionContext.cs
index 087ee28223..f4926ef23c 100644
--- a/src/mscorlib/src/System/Threading/ExecutionContext.cs
+++ b/src/mscorlib/src/System/Threading/ExecutionContext.cs
@@ -63,12 +63,14 @@ 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 IAsyncLocal[] m_localChangeNotifications;
+ private readonly bool m_isFlowSuppressed;
private ExecutionContext()
{
@@ -76,16 +78,83 @@ namespace System.Threading
m_localChangeNotifications = Array.Empty<IAsyncLocal>();
}
- private ExecutionContext(Dictionary<IAsyncLocal, object> localValues, IAsyncLocal[] localChangeNotifications)
+ private ExecutionContext(
+ Dictionary<IAsyncLocal, object> 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;
+ return executionContext == null || executionContext.m_isFlowSuppressed ? Default : executionContext;
+ }
+
+ private ExecutionContext ShallowClone(bool isFlowSuppressed)
+ {
+ Contract.Assert(isFlowSuppressed != m_isFlowSuppressed);
+
+ if (!isFlowSuppressed &&
+ m_localValues == Default.m_localValues &&
+ m_localChangeNotifications == Default.m_localChangeNotifications)
+ {
+ return null; // implies 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, executionContext);
+ 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]
@@ -241,7 +310,8 @@ namespace System.Threading
}
}
- Thread.CurrentThread.ExecutionContext = new ExecutionContext(newValues, newChangeNotifications);
+ Thread.CurrentThread.ExecutionContext =
+ new ExecutionContext(newValues, newChangeNotifications, current.m_isFlowSuppressed);
if (needChangeNotifications)
{
@@ -296,11 +366,6 @@ namespace System.Threading
// For CLR compat only
}
- public static bool IsFlowSuppressed()
- {
- return false;
- }
-
internal static ExecutionContext PreAllocatedDefault
{
[SecuritySafeCritical]
@@ -315,6 +380,72 @@ namespace System.Threading
#endregion
}
+ public struct AsyncFlowControl : IDisposable
+ {
+ private Thread _thread;
+ private ExecutionContext _executionContext;
+
+ internal void Initialize(Thread currentThread, ExecutionContext executionContext)
+ {
+ Contract.Assert(currentThread == Thread.CurrentThread);
+ Contract.Assert(executionContext != null);
+ Contract.Assert(executionContext == currentThread.ExecutionContext);
+
+ _thread = currentThread;
+ _executionContext = executionContext;
+ }
+
+ public void Undo()
+ {
+ if (_thread == null)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCMultiple"));
+ }
+ if (Thread.CurrentThread != _thread)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCOtherThread"));
+ }
+ if (_thread.ExecutionContext != _executionContext)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch"));
+ }
+ Contract.EndContractBlock();
+
+ _thread = null;
+ ExecutionContext.RestoreFlow();
+ }
+
+ public void Dispose()
+ {
+ Undo();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return obj is AsyncFlowControl && Equals((AsyncFlowControl)obj);
+ }
+
+ public bool Equals(AsyncFlowControl obj)
+ {
+ return _thread == obj._thread && _executionContext == obj._executionContext;
+ }
+
+ public override int GetHashCode()
+ {
+ return (_thread?.GetHashCode() ?? 0) + (_executionContext?.GetHashCode() ?? 0);
+ }
+
+ public static bool operator ==(AsyncFlowControl a, AsyncFlowControl b)
+ {
+ return a.Equals(b);
+ }
+
+ public static bool operator !=(AsyncFlowControl a, AsyncFlowControl b)
+ {
+ return !(a == b);
+ }
+ }
+
#else // FEATURE_CORECLR
// Legacy desktop ExecutionContext implementation
@@ -323,7 +454,7 @@ namespace System.Threading
{
internal ExecutionContext.Reader outerEC; // previous EC we need to restore on Undo
internal bool outerECBelongsToScope;
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
internal SecurityContextSwitcher scsw;
#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
internal Object hecsw;
@@ -367,7 +498,7 @@ namespace System.Threading
//
// Restore the HostExecutionContext before restoring the ExecutionContext.
//
-#if FEATURE_CAS_POLICY
+#if FEATURE_CAS_POLICY
if (hecsw != null)
HostExecutionContextSwitcher.Undo(hecsw);
#endif // FEATURE_CAS_POLICY
@@ -467,7 +598,7 @@ namespace System.Threading
}
ExecutionContext.RestoreFlow();
}
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
else
{
if (!Thread.CurrentThread.GetExecutionContextReader().SecurityContext.IsSame(_sc))
@@ -496,7 +627,7 @@ namespace System.Threading
public bool Equals(AsyncFlowControl obj)
{
return obj.useEC == useEC && obj._ec == _ec &&
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
obj._sc == _sc &&
#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
obj._thread == _thread;
@@ -525,7 +656,7 @@ namespace System.Threading
** ExecutionContextObject to maintain alignment between the two classes.
** DON'T CHANGE THESE UNLESS YOU MODIFY ExecutionContextObject in vm\object.h
=========================================================================*/
-#if FEATURE_CAS_POLICY
+#if FEATURE_CAS_POLICY
private HostExecutionContext _hostExecutionContext;
#endif // FEATURE_CAS_POLICY
private SynchronizationContext _syncContext;
@@ -963,9 +1094,9 @@ namespace System.Threading
{
ExecutionContext.Reader ec = currentThread.GetExecutionContextReader();
if ( (ec.IsNull || ec.IsDefaultFTContext(preserveSyncCtx)) &&
- #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
SecurityContext.CurrentlyInDefaultFTSecurityContext(ec) &&
- #endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
executionContext.IsDefaultFTContext(preserveSyncCtx) &&
ec.HasSameLocalValues(executionContext)
)
@@ -1032,7 +1163,7 @@ namespace System.Threading
#endif // FEATURE_CORRUPTING_EXCEPTIONS
internal static ExecutionContextSwitcher SetExecutionContext(ExecutionContext executionContext, bool preserveSyncCtx)
{
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
@@ -1060,7 +1191,7 @@ namespace System.Threading
{
OnAsyncLocalContextChanged(outerEC.DangerousGetRawExecutionContext(), executionContext);
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
//set the security context
SecurityContext sc = executionContext.SecurityContext;
if (sc != null)
@@ -1076,7 +1207,7 @@ namespace System.Threading
ecsw.scsw = SecurityContext.SetSecurityContext(SecurityContext.FullTrustSecurityContext, prevSeC, false, ref stackMark);
}
#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-#if FEATURE_CAS_POLICY
+#if FEATURE_CAS_POLICY
// set the Host Context
HostExecutionContext hostContext = executionContext.HostExecutionContext;
if (hostContext != null)
@@ -1253,7 +1384,7 @@ namespace System.Threading
// Attempt to capture context. There may be nothing to capture...
//
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
// capture the security context
SecurityContext secCtxNew = SecurityContext.Capture(ecCurrent, ref stackMark);
#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
@@ -1294,7 +1425,7 @@ namespace System.Threading
// dummy default EC, don't bother allocating a new context.
//
if (0 != (options & CaptureOptions.OptimizeDefaultCase) &&
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
secCtxNew == null &&
#endif
#if FEATURE_CAS_POLICY
@@ -1315,7 +1446,7 @@ namespace System.Threading
// Allocate the new context, and fill it in.
//
ExecutionContext ecNew = new ExecutionContext();
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
ecNew.SecurityContext = secCtxNew;
if (ecNew.SecurityContext != null)
ecNew.SecurityContext.ExecutionContext = ecNew;
@@ -1378,7 +1509,7 @@ namespace System.Threading
#endif // FEATURE_CAS_POLICY
if (!ignoreSyncCtx && _syncContext != null)
return false;
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
+#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
if (_securityContext != null && !_securityContext.IsDefaultFTSecurityContext())
return false;
#endif //#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
diff --git a/src/mscorlib/src/System/Threading/Thread.cs b/src/mscorlib/src/System/Threading/Thread.cs
index 2788a7b327..4a0d911a55 100644
--- a/src/mscorlib/src/System/Threading/Thread.cs
+++ b/src/mscorlib/src/System/Threading/Thread.cs
@@ -816,14 +816,16 @@ namespace System.Threading {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void InternalFinalize();
+#if !FEATURE_CORECLR
#if FEATURE_COMINTEROP
[System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern void DisableComObjectEagerCleanup();
-#endif //FEATURE_COMINTEROP
+ public new void DisableComObjectEagerCleanup()
+ {
+ base.DisableComObjectEagerCleanup();
+ }
+#endif // FEATURE_COMINTEROP
-#if !FEATURE_CORECLR
/*=========================================================================
** Return whether or not this thread is a background thread. Background
** threads do not affect when the Execution Engine shuts down.
diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h
index 1ac8f39197..331bfe66cc 100644
--- a/src/vm/ecalllist.h
+++ b/src/vm/ecalllist.h
@@ -1278,6 +1278,9 @@ FCFuncStart(gRuntimeThreadFuncs)
FCFuncElement("GetApartmentStateNative", ThreadNative::GetApartmentState)
FCFuncElement("SetApartmentStateNative", ThreadNative::SetApartmentState)
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
+#ifdef FEATURE_COMINTEROP
+ FCFuncElement("DisableComObjectEagerCleanup", ThreadNative::DisableComObjectEagerCleanup)
+#endif // FEATURE_COMINTEROP
FCFuncElement("InterruptInternal", ThreadNative::Interrupt)
FCFuncElement("JoinInternal", ThreadNative::Join)
FCFuncEnd()
@@ -1329,9 +1332,6 @@ FCFuncStart(gThreadFuncs)
FCIntrinsic("GetCurrentThreadNative", ThreadNative::GetCurrentThread, CORINFO_INTRINSIC_GetCurrentManagedThread)
FCIntrinsic("get_ManagedThreadId", ThreadNative::GetManagedThreadId, CORINFO_INTRINSIC_GetManagedThreadId)
FCFuncElement("InternalFinalize", ThreadNative::Finalize)
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- FCFuncElement("DisableComObjectEagerCleanup", ThreadNative::DisableComObjectEagerCleanup)
-#endif // defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
#ifdef FEATURE_LEAK_CULTURE_INFO
FCFuncElement("nativeSetThreadUILocale", ThreadNative::SetThreadUILocale)
#endif
@@ -1348,9 +1348,7 @@ FCFuncEnd()
FCFuncStart(gThreadPoolFuncs)
FCFuncElement("PostQueuedCompletionStatus", ThreadPoolNative::CorPostQueuedCompletionStatus)
-#ifndef FEATURE_CORECLR
FCFuncElement("GetAvailableThreadsNative", ThreadPoolNative::CorGetAvailableThreads)
-#endif // FEATURE_CORECLR
FCFuncElement("SetMinThreadsNative", ThreadPoolNative::CorSetMinThreads)
FCFuncElement("GetMinThreadsNative", ThreadPoolNative::CorGetMinThreads)
FCFuncElement("RegisterWaitForSingleObjectNative", ThreadPoolNative::CorRegisterWaitForSingleObject)
diff --git a/src/vm/object.h b/src/vm/object.h
index d4ab9ef19e..d3abce28dd 100644
--- a/src/vm/object.h
+++ b/src/vm/object.h
@@ -2192,15 +2192,28 @@ public:
}
#endif // FEATURE_LEAK_CULTURE_INFO
-#ifndef FEATURE_CORECLR
+#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
+#ifdef FEATURE_CORECLR
OBJECTREF GetSynchronizationContext()
{
- LIMITED_METHOD_CONTRACT;
+ LIMITED_METHOD_CONTRACT;
+ return m_SynchronizationContext;
+ }
+#else // !FEATURE_CORECLR
+ OBJECTREF GetSynchronizationContext()
+ {
+ LIMITED_METHOD_CONTRACT;
if (m_ExecutionContext != NULL)
+ {
return m_ExecutionContext->GetSynchronizationContext();
+ }
return NULL;
}
- OBJECTREF GetExecutionContext()
+#endif // FEATURE_CORECLR
+#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
+
+#ifndef FEATURE_CORECLR
+ OBJECTREF GetExecutionContext()
{
LIMITED_METHOD_CONTRACT;
return (OBJECTREF)m_ExecutionContext;
diff --git a/src/vm/threads.h b/src/vm/threads.h
index bb54a85f45..a4131948ad 100644
--- a/src/vm/threads.h
+++ b/src/vm/threads.h
@@ -2796,7 +2796,8 @@ public:
CONTRACTL_END;
return (ObjectFromHandle(m_ExposedObject) != NULL) ;
}
-#ifndef FEATURE_CORECLR
+
+#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
void GetSynchronizationContext(OBJECTREF *pSyncContextObj)
{
CONTRACTL
@@ -2814,7 +2815,8 @@ public:
if (ExposedThreadObj != NULL)
*pSyncContextObj = ExposedThreadObj->GetSynchronizationContext();
}
-#endif //!FEATURE_CORECLR
+#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
+
#ifdef FEATURE_COMPRESSEDSTACK
OBJECTREF GetCompressedStack()
{