Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / clr / src / BCL / System / Threading / ExecutionContext.cs / 1 / ExecutionContext.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // /*============================================================ ** ** Class: ExecutionContext ** ** ** Purpose: Capture execution context for a thread ** ** ===========================================================*/ namespace System.Threading { using System; using System.Security; using System.Runtime.Remoting; using System.Security.Principal; using System.Collections; using System.Reflection; using System.Runtime.Serialization; using System.Security.Permissions; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; internal enum ExceptionType { InvalidOperation = 0, Security = 1, EE = 2, Generic = 3 } // helper delegate to statically bind to Wait method internal delegate int WaitDelegate(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout); internal struct ExecutionContextSwitcher: IDisposable { internal ExecutionContext prevEC; // previous EC we need to restore on Undo internal ExecutionContext currEC; // current EC that we store for checking correctness internal SecurityContextSwitcher scsw; internal SynchronizationContextSwitcher sysw; internal Object hecsw; internal Thread thread; public override bool Equals(Object obj) { if (obj == null || !(obj is ExecutionContextSwitcher)) return false; ExecutionContextSwitcher sw = (ExecutionContextSwitcher)obj; return (this.prevEC == sw.prevEC && this.currEC == sw.currEC && this.scsw == sw.scsw && this.sysw == sw.sysw && this.hecsw == sw.hecsw && this.thread == sw.thread); } public override int GetHashCode() { return ToString().GetHashCode(); } public static bool operator ==(ExecutionContextSwitcher c1, ExecutionContextSwitcher c2) { return c1.Equals(c2); } public static bool operator !=(ExecutionContextSwitcher c1, ExecutionContextSwitcher c2) { return !c1.Equals(c2); } ///void IDisposable.Dispose() { Undo(); } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal bool UndoNoThrow() { try { Undo(); } catch { return false; } return true; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public void Undo() { if (thread == null) { return; // Don't do anything } if (thread != Thread.CurrentThread) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseSwitcherOtherThread")); } if ( currEC != Thread.CurrentThread.GetExecutionContextNoCreate()) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SwitcherCtxMismatch")); } BCLDebug.Assert(currEC != null, " ExecutionContext can't be null"); // Any critical failure inside scsw will cause FailFast scsw.Undo(); try { HostExecutionContextSwitcher.Undo(hecsw); } finally { // Even if HostExecutionContextSwitcher.Undo(hecsw) throws, we need to revert // synchronizationContext. If that throws, we'll be throwing an ex during an exception // unwind. That's OK - we'll just have nested exceptions. sysw.Undo(); } // restore the saved Execution Context Thread.CurrentThread.SetExecutionContext(prevEC); thread = null; // this will prevent the switcher object being used again } } public struct AsyncFlowControl: IDisposable { private bool useEC; private ExecutionContext _ec; private SecurityContext _sc; private Thread _thread; internal void Setup(SecurityContextDisableFlow flags) { useEC = false; _sc = Thread.CurrentThread.ExecutionContext.SecurityContext; _sc._disableFlow = flags; _thread = Thread.CurrentThread; } internal void Setup() { useEC = true; _ec = Thread.CurrentThread.ExecutionContext; _ec.isFlowSuppressed = true; _thread = Thread.CurrentThread; } /// void IDisposable.Dispose() { Undo(); } 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.ExecutionContext != _ec) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch")); } ExecutionContext.RestoreFlow(); } else { if (Thread.CurrentThread.ExecutionContext.SecurityContext != _sc) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch")); } SecurityContext.RestoreFlow(); } _thread = null; } public override int GetHashCode() { // review - [....] 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 && obj._sc == _sc && 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); } } [System.Runtime.InteropServices.ComVisible(true)] public delegate void ContextCallback(Object state); [Serializable()] public sealed class ExecutionContext : 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 =========================================================================*/ private HostExecutionContext _hostExecutionContext; private SynchronizationContext _syncContext; private SecurityContext _securityContext; private LogicalCallContext _logicalCallContext; private IllogicalCallContext _illogicalCallContext; // this call context follows the physical thread private Thread _thread; internal bool isNewCapture = false; internal bool isFlowSuppressed = false; [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal ExecutionContext() { } internal LogicalCallContext LogicalCallContext { get { if (_logicalCallContext == null) { _logicalCallContext = new LogicalCallContext(); } return _logicalCallContext; } set { _logicalCallContext = value; } } internal IllogicalCallContext IllogicalCallContext { get { if (_illogicalCallContext == null) { _illogicalCallContext = new IllogicalCallContext(); } return _illogicalCallContext; } set { _illogicalCallContext = value; } } internal Thread Thread { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] set { _thread = value; } } internal SynchronizationContext SynchronizationContext { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return _syncContext; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] set { _syncContext = value; } } internal HostExecutionContext HostExecutionContext { get { return _hostExecutionContext; } set { _hostExecutionContext = value; } } internal SecurityContext SecurityContext { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return _securityContext; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] set { // store the new security context _securityContext = value; // perform the reverse link too if (value != null) _securityContext.ExecutionContext = this; } } [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure), DynamicSecurityMethodAttribute()] 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")); } executionContext.isNewCapture = false; ExecutionContext ec = Thread.CurrentThread.GetExecutionContextNoCreate(); if ( (ec == null || ec.IsDefaultFTContext()) && SecurityContext.CurrentlyInDefaultFTSecurityContext(ec) && executionContext.IsDefaultFTContext()) { callback(state); } else { RunInternal(executionContext, callback, state); } } internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) { if (cleanupCode == null) { tryCode = new RuntimeHelpers.TryCode(runTryCode); cleanupCode = new RuntimeHelpers.CleanupCode(runFinallyCode); } ExecutionContextRunData runData = new ExecutionContextRunData(executionContext, callback, state); RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(tryCode, cleanupCode, runData); } internal class ExecutionContextRunData { internal ExecutionContext ec; internal ContextCallback callBack; internal Object state; internal ExecutionContextSwitcher ecsw; internal ExecutionContextRunData(ExecutionContext executionContext, ContextCallback cb, Object state) { this.ec = executionContext; this.callBack = cb; this.state = state; ecsw = new ExecutionContextSwitcher(); } } static internal void runTryCode(Object userData) { ExecutionContextRunData rData = (ExecutionContextRunData) userData; rData.ecsw = SetExecutionContext(rData.ec); rData.callBack(rData.state); } [PrePrepareMethod] static internal void runFinallyCode(Object userData, bool exceptionThrown) { ExecutionContextRunData rData = (ExecutionContextRunData) userData; rData.ecsw.Undo(); } static internal RuntimeHelpers.TryCode tryCode; static internal RuntimeHelpers.CleanupCode cleanupCode; // Sets the given execution context object on the thread. // Returns the previous one. [DynamicSecurityMethodAttribute()] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable internal static ExecutionContextSwitcher SetExecutionContext(ExecutionContext executionContext) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; BCLDebug.Assert(executionContext != null, "ExecutionContext cannot be null here."); // Set up the switcher object to return; ExecutionContextSwitcher ecsw = new ExecutionContextSwitcher(); ecsw.thread = Thread.CurrentThread; ecsw.prevEC = Thread.CurrentThread.GetExecutionContextNoCreate(); // prev ecsw.currEC = executionContext; //current // Update the EC on thread Thread.CurrentThread.SetExecutionContext(executionContext); RuntimeHelpers.PrepareConstrainedRegions(); try { if (executionContext != null) { //set the security context SecurityContext sc = executionContext.SecurityContext; if (sc != null) { // non-null SC: needs to be set SecurityContext prevSeC = (ecsw.prevEC != null) ? ecsw.prevEC.SecurityContext : null; ecsw.scsw = SecurityContext.SetSecurityContext(sc, prevSeC, ref stackMark); } else if (!SecurityContext.CurrentlyInDefaultFTSecurityContext(ecsw.prevEC)) { // null incoming SC, but we're currently not in FT: use static FTSC to set SecurityContext prevSeC = (ecsw.prevEC != null) ? ecsw.prevEC.SecurityContext : null; ecsw.scsw = SecurityContext.SetSecurityContext(SecurityContext.FullTrustSecurityContext, prevSeC, ref stackMark); } // set the [....] context SynchronizationContext syncContext = executionContext.SynchronizationContext; if (syncContext != null) { SynchronizationContext prevSyC = (ecsw.prevEC != null) ? ecsw.prevEC.SynchronizationContext : null; ecsw.sysw = SynchronizationContext.SetSynchronizationContext(syncContext, prevSyC); } // set the Host Context HostExecutionContext hostContext = executionContext.HostExecutionContext; if (hostContext != null) { ecsw.hecsw = HostExecutionContextManager.SetHostExecutionContextInternal(hostContext); } } } catch { ecsw.UndoNoThrow(); throw; } return ecsw; } 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(); // capture the host execution context ec._hostExecutionContext = _hostExecutionContext == null ? null : _hostExecutionContext.CreateCopy(); if (_securityContext != null) { ec._securityContext = _securityContext.CreateCopy(); ec._securityContext.ExecutionContext = ec; } if (this._logicalCallContext != null) { LogicalCallContext lc = (LogicalCallContext)this.LogicalCallContext; ec.LogicalCallContext = (LogicalCallContext)lc.Clone(); } if (this._illogicalCallContext != null) { IllogicalCallContext ilcc = (IllogicalCallContext)this.IllogicalCallContext; ec.IllogicalCallContext = (IllogicalCallContext)ilcc.Clone(); } return ec; } [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)] public static AsyncFlowControl SuppressFlow() { if (IsFlowSuppressed()) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotSupressFlowMultipleTimes")); } AsyncFlowControl afc = new AsyncFlowControl(); afc.Setup(); return afc; } public static void RestoreFlow() { ExecutionContext ec = Thread.CurrentThread.GetExecutionContextNoCreate(); if (ec == null || !ec.isFlowSuppressed) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRestoreUnsupressedFlow")); } ec.isFlowSuppressed = false; } public static bool IsFlowSuppressed() { ExecutionContext ec = Thread.CurrentThread.GetExecutionContextNoCreate(); if (ec == null) return false; else return ec.isFlowSuppressed; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static ExecutionContext Capture() { // set up a stack mark for finding the caller StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return ExecutionContext.Capture(ref stackMark); } // internal helper to capture the current execution context using a passed in stack mark static internal ExecutionContext Capture(ref StackCrawlMark stackMark) { // check to see if Flow is suppressed if (IsFlowSuppressed()) return null; ExecutionContext ecCurrent = Thread.CurrentThread.GetExecutionContextNoCreate(); ExecutionContext ecNew = new ExecutionContext(); ecNew.isNewCapture = true; // capture the security context ecNew.SecurityContext = SecurityContext.Capture(ecCurrent, ref stackMark); if (ecNew.SecurityContext != null) ecNew.SecurityContext.ExecutionContext = ecNew; // capture the host execution context ecNew._hostExecutionContext = HostExecutionContextManager.CaptureHostExecutionContext(); if (ecCurrent != null) { // capture the [....] context ecNew._syncContext = (ecCurrent._syncContext == null) ?null: ecCurrent._syncContext.CreateCopy(); // copy over the Logical Call Context if (ecCurrent._logicalCallContext != null) { LogicalCallContext lc = (LogicalCallContext)ecCurrent.LogicalCallContext; ecNew.LogicalCallContext = (LogicalCallContext)lc.Clone(); } } return ecNew; } // // Implementation of ISerializable // [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)] public void GetObjectData(SerializationInfo info, StreamingContext context) { if (info==null) throw new ArgumentNullException("info"); if (_logicalCallContext != null) { info.AddValue("LogicalCallContext", _logicalCallContext, typeof(LogicalCallContext)); } } private ExecutionContext(SerializationInfo info, StreamingContext context) { SerializationInfoEnumerator e = info.GetEnumerator(); while (e.MoveNext()) { if (e.Name.Equals("LogicalCallContext")) { _logicalCallContext = (LogicalCallContext) e.Value; } } this.Thread = Thread.CurrentThread; } // ObjRef .ctor static internal void ClearSyncContext(ExecutionContext ec) { if (ec != null) ec.SynchronizationContext = null; } internal bool IsDefaultFTContext() { if (_hostExecutionContext != null) return false; if (_syncContext != null) return false; if (_securityContext != null && !_securityContext.IsDefaultFTSecurityContext()) return false; if (_logicalCallContext != null && _logicalCallContext.HasInfo) return false; if (_illogicalCallContext != null && _illogicalCallContext.HasUserData) return false; return true; } } // class ExecutionContext } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // /*============================================================ ** ** Class: ExecutionContext ** ** ** Purpose: Capture execution context for a thread ** ** ===========================================================*/ namespace System.Threading { using System; using System.Security; using System.Runtime.Remoting; using System.Security.Principal; using System.Collections; using System.Reflection; using System.Runtime.Serialization; using System.Security.Permissions; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; internal enum ExceptionType { InvalidOperation = 0, Security = 1, EE = 2, Generic = 3 } // helper delegate to statically bind to Wait method internal delegate int WaitDelegate(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout); internal struct ExecutionContextSwitcher: IDisposable { internal ExecutionContext prevEC; // previous EC we need to restore on Undo internal ExecutionContext currEC; // current EC that we store for checking correctness internal SecurityContextSwitcher scsw; internal SynchronizationContextSwitcher sysw; internal Object hecsw; internal Thread thread; public override bool Equals(Object obj) { if (obj == null || !(obj is ExecutionContextSwitcher)) return false; ExecutionContextSwitcher sw = (ExecutionContextSwitcher)obj; return (this.prevEC == sw.prevEC && this.currEC == sw.currEC && this.scsw == sw.scsw && this.sysw == sw.sysw && this.hecsw == sw.hecsw && this.thread == sw.thread); } public override int GetHashCode() { return ToString().GetHashCode(); } public static bool operator ==(ExecutionContextSwitcher c1, ExecutionContextSwitcher c2) { return c1.Equals(c2); } public static bool operator !=(ExecutionContextSwitcher c1, ExecutionContextSwitcher c2) { return !c1.Equals(c2); } /// void IDisposable.Dispose() { Undo(); } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal bool UndoNoThrow() { try { Undo(); } catch { return false; } return true; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public void Undo() { if (thread == null) { return; // Don't do anything } if (thread != Thread.CurrentThread) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseSwitcherOtherThread")); } if ( currEC != Thread.CurrentThread.GetExecutionContextNoCreate()) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SwitcherCtxMismatch")); } BCLDebug.Assert(currEC != null, " ExecutionContext can't be null"); // Any critical failure inside scsw will cause FailFast scsw.Undo(); try { HostExecutionContextSwitcher.Undo(hecsw); } finally { // Even if HostExecutionContextSwitcher.Undo(hecsw) throws, we need to revert // synchronizationContext. If that throws, we'll be throwing an ex during an exception // unwind. That's OK - we'll just have nested exceptions. sysw.Undo(); } // restore the saved Execution Context Thread.CurrentThread.SetExecutionContext(prevEC); thread = null; // this will prevent the switcher object being used again } } public struct AsyncFlowControl: IDisposable { private bool useEC; private ExecutionContext _ec; private SecurityContext _sc; private Thread _thread; internal void Setup(SecurityContextDisableFlow flags) { useEC = false; _sc = Thread.CurrentThread.ExecutionContext.SecurityContext; _sc._disableFlow = flags; _thread = Thread.CurrentThread; } internal void Setup() { useEC = true; _ec = Thread.CurrentThread.ExecutionContext; _ec.isFlowSuppressed = true; _thread = Thread.CurrentThread; } /// void IDisposable.Dispose() { Undo(); } 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.ExecutionContext != _ec) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch")); } ExecutionContext.RestoreFlow(); } else { if (Thread.CurrentThread.ExecutionContext.SecurityContext != _sc) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch")); } SecurityContext.RestoreFlow(); } _thread = null; } public override int GetHashCode() { // review - [....] 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 && obj._sc == _sc && 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); } } [System.Runtime.InteropServices.ComVisible(true)] public delegate void ContextCallback(Object state); [Serializable()] public sealed class ExecutionContext : 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 =========================================================================*/ private HostExecutionContext _hostExecutionContext; private SynchronizationContext _syncContext; private SecurityContext _securityContext; private LogicalCallContext _logicalCallContext; private IllogicalCallContext _illogicalCallContext; // this call context follows the physical thread private Thread _thread; internal bool isNewCapture = false; internal bool isFlowSuppressed = false; [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal ExecutionContext() { } internal LogicalCallContext LogicalCallContext { get { if (_logicalCallContext == null) { _logicalCallContext = new LogicalCallContext(); } return _logicalCallContext; } set { _logicalCallContext = value; } } internal IllogicalCallContext IllogicalCallContext { get { if (_illogicalCallContext == null) { _illogicalCallContext = new IllogicalCallContext(); } return _illogicalCallContext; } set { _illogicalCallContext = value; } } internal Thread Thread { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] set { _thread = value; } } internal SynchronizationContext SynchronizationContext { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return _syncContext; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] set { _syncContext = value; } } internal HostExecutionContext HostExecutionContext { get { return _hostExecutionContext; } set { _hostExecutionContext = value; } } internal SecurityContext SecurityContext { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return _securityContext; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] set { // store the new security context _securityContext = value; // perform the reverse link too if (value != null) _securityContext.ExecutionContext = this; } } [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure), DynamicSecurityMethodAttribute()] 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")); } executionContext.isNewCapture = false; ExecutionContext ec = Thread.CurrentThread.GetExecutionContextNoCreate(); if ( (ec == null || ec.IsDefaultFTContext()) && SecurityContext.CurrentlyInDefaultFTSecurityContext(ec) && executionContext.IsDefaultFTContext()) { callback(state); } else { RunInternal(executionContext, callback, state); } } internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) { if (cleanupCode == null) { tryCode = new RuntimeHelpers.TryCode(runTryCode); cleanupCode = new RuntimeHelpers.CleanupCode(runFinallyCode); } ExecutionContextRunData runData = new ExecutionContextRunData(executionContext, callback, state); RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(tryCode, cleanupCode, runData); } internal class ExecutionContextRunData { internal ExecutionContext ec; internal ContextCallback callBack; internal Object state; internal ExecutionContextSwitcher ecsw; internal ExecutionContextRunData(ExecutionContext executionContext, ContextCallback cb, Object state) { this.ec = executionContext; this.callBack = cb; this.state = state; ecsw = new ExecutionContextSwitcher(); } } static internal void runTryCode(Object userData) { ExecutionContextRunData rData = (ExecutionContextRunData) userData; rData.ecsw = SetExecutionContext(rData.ec); rData.callBack(rData.state); } [PrePrepareMethod] static internal void runFinallyCode(Object userData, bool exceptionThrown) { ExecutionContextRunData rData = (ExecutionContextRunData) userData; rData.ecsw.Undo(); } static internal RuntimeHelpers.TryCode tryCode; static internal RuntimeHelpers.CleanupCode cleanupCode; // Sets the given execution context object on the thread. // Returns the previous one. [DynamicSecurityMethodAttribute()] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable internal static ExecutionContextSwitcher SetExecutionContext(ExecutionContext executionContext) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; BCLDebug.Assert(executionContext != null, "ExecutionContext cannot be null here."); // Set up the switcher object to return; ExecutionContextSwitcher ecsw = new ExecutionContextSwitcher(); ecsw.thread = Thread.CurrentThread; ecsw.prevEC = Thread.CurrentThread.GetExecutionContextNoCreate(); // prev ecsw.currEC = executionContext; //current // Update the EC on thread Thread.CurrentThread.SetExecutionContext(executionContext); RuntimeHelpers.PrepareConstrainedRegions(); try { if (executionContext != null) { //set the security context SecurityContext sc = executionContext.SecurityContext; if (sc != null) { // non-null SC: needs to be set SecurityContext prevSeC = (ecsw.prevEC != null) ? ecsw.prevEC.SecurityContext : null; ecsw.scsw = SecurityContext.SetSecurityContext(sc, prevSeC, ref stackMark); } else if (!SecurityContext.CurrentlyInDefaultFTSecurityContext(ecsw.prevEC)) { // null incoming SC, but we're currently not in FT: use static FTSC to set SecurityContext prevSeC = (ecsw.prevEC != null) ? ecsw.prevEC.SecurityContext : null; ecsw.scsw = SecurityContext.SetSecurityContext(SecurityContext.FullTrustSecurityContext, prevSeC, ref stackMark); } // set the [....] context SynchronizationContext syncContext = executionContext.SynchronizationContext; if (syncContext != null) { SynchronizationContext prevSyC = (ecsw.prevEC != null) ? ecsw.prevEC.SynchronizationContext : null; ecsw.sysw = SynchronizationContext.SetSynchronizationContext(syncContext, prevSyC); } // set the Host Context HostExecutionContext hostContext = executionContext.HostExecutionContext; if (hostContext != null) { ecsw.hecsw = HostExecutionContextManager.SetHostExecutionContextInternal(hostContext); } } } catch { ecsw.UndoNoThrow(); throw; } return ecsw; } 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(); // capture the host execution context ec._hostExecutionContext = _hostExecutionContext == null ? null : _hostExecutionContext.CreateCopy(); if (_securityContext != null) { ec._securityContext = _securityContext.CreateCopy(); ec._securityContext.ExecutionContext = ec; } if (this._logicalCallContext != null) { LogicalCallContext lc = (LogicalCallContext)this.LogicalCallContext; ec.LogicalCallContext = (LogicalCallContext)lc.Clone(); } if (this._illogicalCallContext != null) { IllogicalCallContext ilcc = (IllogicalCallContext)this.IllogicalCallContext; ec.IllogicalCallContext = (IllogicalCallContext)ilcc.Clone(); } return ec; } [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)] public static AsyncFlowControl SuppressFlow() { if (IsFlowSuppressed()) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotSupressFlowMultipleTimes")); } AsyncFlowControl afc = new AsyncFlowControl(); afc.Setup(); return afc; } public static void RestoreFlow() { ExecutionContext ec = Thread.CurrentThread.GetExecutionContextNoCreate(); if (ec == null || !ec.isFlowSuppressed) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRestoreUnsupressedFlow")); } ec.isFlowSuppressed = false; } public static bool IsFlowSuppressed() { ExecutionContext ec = Thread.CurrentThread.GetExecutionContextNoCreate(); if (ec == null) return false; else return ec.isFlowSuppressed; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static ExecutionContext Capture() { // set up a stack mark for finding the caller StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return ExecutionContext.Capture(ref stackMark); } // internal helper to capture the current execution context using a passed in stack mark static internal ExecutionContext Capture(ref StackCrawlMark stackMark) { // check to see if Flow is suppressed if (IsFlowSuppressed()) return null; ExecutionContext ecCurrent = Thread.CurrentThread.GetExecutionContextNoCreate(); ExecutionContext ecNew = new ExecutionContext(); ecNew.isNewCapture = true; // capture the security context ecNew.SecurityContext = SecurityContext.Capture(ecCurrent, ref stackMark); if (ecNew.SecurityContext != null) ecNew.SecurityContext.ExecutionContext = ecNew; // capture the host execution context ecNew._hostExecutionContext = HostExecutionContextManager.CaptureHostExecutionContext(); if (ecCurrent != null) { // capture the [....] context ecNew._syncContext = (ecCurrent._syncContext == null) ?null: ecCurrent._syncContext.CreateCopy(); // copy over the Logical Call Context if (ecCurrent._logicalCallContext != null) { LogicalCallContext lc = (LogicalCallContext)ecCurrent.LogicalCallContext; ecNew.LogicalCallContext = (LogicalCallContext)lc.Clone(); } } return ecNew; } // // Implementation of ISerializable // [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)] public void GetObjectData(SerializationInfo info, StreamingContext context) { if (info==null) throw new ArgumentNullException("info"); if (_logicalCallContext != null) { info.AddValue("LogicalCallContext", _logicalCallContext, typeof(LogicalCallContext)); } } private ExecutionContext(SerializationInfo info, StreamingContext context) { SerializationInfoEnumerator e = info.GetEnumerator(); while (e.MoveNext()) { if (e.Name.Equals("LogicalCallContext")) { _logicalCallContext = (LogicalCallContext) e.Value; } } this.Thread = Thread.CurrentThread; } // ObjRef .ctor static internal void ClearSyncContext(ExecutionContext ec) { if (ec != null) ec.SynchronizationContext = null; } internal bool IsDefaultFTContext() { if (_hostExecutionContext != null) return false; if (_syncContext != null) return false; if (_securityContext != null && !_securityContext.IsDefaultFTSecurityContext()) return false; if (_logicalCallContext != null && _logicalCallContext.HasInfo) return false; if (_illogicalCallContext != null && _illogicalCallContext.HasUserData) return false; return true; } } // class ExecutionContext } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- IisTraceWebEventProvider.cs
- SafeSecurityHandles.cs
- SecurityStateEncoder.cs
- TranslateTransform.cs
- OrderedDictionary.cs
- PkcsMisc.cs
- MailFileEditor.cs
- HostExecutionContextManager.cs
- LockCookie.cs
- ToolStripRenderEventArgs.cs
- FlowNode.cs
- InvalidFilterCriteriaException.cs
- SafeNativeMethods.cs
- PropertyGrid.cs
- SoapTypeAttribute.cs
- ManifestResourceInfo.cs
- _SSPISessionCache.cs
- DateTimeConstantAttribute.cs
- ProcessModelInfo.cs
- PageThemeParser.cs
- EventLogPermissionEntry.cs
- FontTypeConverter.cs
- _Semaphore.cs
- SqlNamer.cs
- ToolStripSeparator.cs
- SessionIDManager.cs
- StateRuntime.cs
- HashRepartitionStream.cs
- EmissiveMaterial.cs
- TextElementEditingBehaviorAttribute.cs
- RowsCopiedEventArgs.cs
- ControllableStoryboardAction.cs
- SqlDataSourceCommandParser.cs
- NameNode.cs
- HttpCachePolicy.cs
- SpellerInterop.cs
- DrawingVisualDrawingContext.cs
- TransactionFlowElement.cs
- HwndTarget.cs
- FormViewPageEventArgs.cs
- VirtualizingStackPanel.cs
- TimeSpanOrInfiniteConverter.cs
- GridViewHeaderRowPresenter.cs
- Matrix3DValueSerializer.cs
- NetCodeGroup.cs
- AutoResizedEvent.cs
- ResXBuildProvider.cs
- DataGridViewComboBoxColumnDesigner.cs
- SQLGuidStorage.cs
- EditBehavior.cs
- ConsoleCancelEventArgs.cs
- cryptoapiTransform.cs
- ReadWriteSpinLock.cs
- MimeWriter.cs
- CounterSampleCalculator.cs
- ApplicationDirectory.cs
- InputManager.cs
- DataRowExtensions.cs
- EpmHelper.cs
- ReflectPropertyDescriptor.cs
- InternalConfigEventArgs.cs
- SimpleWebHandlerParser.cs
- HttpHandlersInstallComponent.cs
- SecurityHelper.cs
- SafeNativeMethods.cs
- SimpleApplicationHost.cs
- RightsManagementEncryptedStream.cs
- formatter.cs
- LineSegment.cs
- RSACryptoServiceProvider.cs
- NonSerializedAttribute.cs
- ColorTranslator.cs
- MostlySingletonList.cs
- EmptyStringExpandableObjectConverter.cs
- XamlStream.cs
- TimeSpanSecondsOrInfiniteConverter.cs
- SyntaxCheck.cs
- XLinq.cs
- PeerApplication.cs
- URLEditor.cs
- OutputCacheModule.cs
- EncryptedXml.cs
- SeekStoryboard.cs
- TreeNodeEventArgs.cs
- GridViewRowCollection.cs
- MissingManifestResourceException.cs
- RichTextBox.cs
- DataGridViewRow.cs
- UnmanagedMemoryStreamWrapper.cs
- ItemCollection.cs
- HttpListenerRequestUriBuilder.cs
- Parsers.cs
- SelectorItemAutomationPeer.cs
- EntityProxyTypeInfo.cs
- BuildProvidersCompiler.cs
- ApplicationTrust.cs
- DataGridCellInfo.cs
- IndexedString.cs
- TypeConverterValueSerializer.cs
- ValueUtilsSmi.cs