Expose some things for ns2.0
authorKoundinya Veluri <kouvel@microsoft.com>
Mon, 7 Nov 2016 03:25:29 +0000 (19:25 -0800)
committerKoundinya Veluri <kouvel@microsoft.com>
Fri, 11 Nov 2016 03:51:33 +0000 (19:51 -0800)
Mostly:
- Exposed flow-related methods on `ExecutionContext`
- Enabled and exposed `SynchronizationContext` wait overriding

Realted issues:
- dotnet/corefxdotnet/coreclr#11638
- dotnet/corefxdotnet/coreclr#11633
- dotnet/corefxdotnet/coreclr#11635
- dotnet/corefxdotnet/coreclr#11636
- dotnet/corefxdotnet/coreclr#13484

Commit migrated from https://github.com/dotnet/coreclr/commit/9c1550e443a73cd072608ea18f846f16441b4db3

src/coreclr/clr.coreclr.props
src/coreclr/clr.defines.targets
src/coreclr/clrdefinitions.cmake
src/coreclr/src/mscorlib/model.xml
src/coreclr/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs
src/coreclr/src/mscorlib/src/System/Threading/ExecutionContext.cs
src/coreclr/src/mscorlib/src/System/Threading/Thread.cs
src/coreclr/src/vm/ecalllist.h
src/coreclr/src/vm/object.h
src/coreclr/src/vm/threads.h

index 26e2118..8ff0f0b 100644 (file)
@@ -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>
index e7b0e86..a45d0dd 100644 (file)
@@ -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>
index 3803d57..99f1ad1 100644 (file)
@@ -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)
index 8d8ff11..46bab1e 100644 (file)
     </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" />
       <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" />
       <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" />
index b391bad..419ad92 100644 (file)
@@ -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);
index 087ee28..f4926ef 100644 (file)
@@ -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
index 2788a7b..4a0d911 100644 (file)
@@ -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.
index 1ac8f39..331bfe6 100644 (file)
@@ -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)
index d4ab9ef..d3abce2 100644 (file)
@@ -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;
index bb54a85..a413194 100644 (file)
@@ -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()
     {