diff options
author | Koundinya Veluri <kouvel@microsoft.com> | 2016-11-06 19:25:29 -0800 |
---|---|---|
committer | Koundinya Veluri <kouvel@microsoft.com> | 2016-11-10 19:51:33 -0800 |
commit | 9c1550e443a73cd072608ea18f846f16441b4db3 (patch) | |
tree | 1760f8aa1851d1fcaedbb7ebc7c02971c83854ad | |
parent | 1b0dad67bc88bd4a45f59e63c6bf9fd5e7eb8596 (diff) | |
download | coreclr-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.props | 1 | ||||
-rw-r--r-- | clr.defines.targets | 1 | ||||
-rw-r--r-- | clrdefinitions.cmake | 1 | ||||
-rw-r--r-- | src/mscorlib/model.xml | 47 | ||||
-rw-r--r-- | src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs | 38 | ||||
-rw-r--r-- | src/mscorlib/src/System/Threading/ExecutionContext.cs | 177 | ||||
-rw-r--r-- | src/mscorlib/src/System/Threading/Thread.cs | 10 | ||||
-rw-r--r-- | src/vm/ecalllist.h | 8 | ||||
-rw-r--r-- | src/vm/object.h | 19 | ||||
-rw-r--r-- | src/vm/threads.h | 6 |
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() { |