Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / 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
- ColorBlend.cs
- XPathParser.cs
- XmlText.cs
- InstanceDataCollection.cs
- ChannelBinding.cs
- LiteralTextContainerControlBuilder.cs
- DataGridViewCellConverter.cs
- BaseProcessor.cs
- ObjectConverter.cs
- XmlSchemaSubstitutionGroup.cs
- _ScatterGatherBuffers.cs
- ConfigErrorGlyph.cs
- UIHelper.cs
- NavigationHelper.cs
- HtmlElementCollection.cs
- SystemResources.cs
- DrawItemEvent.cs
- EdmConstants.cs
- UrlPath.cs
- TextEffectResolver.cs
- MenuAdapter.cs
- CheckableControlBaseAdapter.cs
- ResourceProviderFactory.cs
- ProfilePropertyNameValidator.cs
- AttributeData.cs
- ToolStripDropTargetManager.cs
- WebPartManagerInternals.cs
- Parameter.cs
- SrgsElementFactoryCompiler.cs
- Memoizer.cs
- DataGridAddNewRow.cs
- GraphicsContainer.cs
- ThrowHelper.cs
- XPathParser.cs
- JoinElimination.cs
- _CookieModule.cs
- ToolStripItemClickedEventArgs.cs
- SpeechRecognizer.cs
- KeyGestureConverter.cs
- PointHitTestResult.cs
- XmlDeclaration.cs
- ReadOnlyDictionary.cs
- Drawing.cs
- ApplicationFileParser.cs
- DataGridViewCellStateChangedEventArgs.cs
- InheritanceRules.cs
- Triangle.cs
- VisualStyleInformation.cs
- UriTemplateMatch.cs
- DataRelation.cs
- WebPartConnectionsCloseVerb.cs
- ItemContainerProviderWrapper.cs
- CodeArrayIndexerExpression.cs
- TransactionFlowBindingElementImporter.cs
- TabItem.cs
- DataGridParentRows.cs
- ReflectEventDescriptor.cs
- MultipartIdentifier.cs
- TrackingMemoryStream.cs
- DataFormats.cs
- StylusCaptureWithinProperty.cs
- Propagator.cs
- ResXBuildProvider.cs
- CryptoProvider.cs
- EventLog.cs
- TcpTransportElement.cs
- Geometry.cs
- EntityException.cs
- WarningException.cs
- smtpconnection.cs
- CodeAttributeDeclarationCollection.cs
- DataGridView.cs
- BinaryEditor.cs
- BooleanExpr.cs
- CodeParameterDeclarationExpression.cs
- ToolBarTray.cs
- _Win32.cs
- RoleProviderPrincipal.cs
- ForceCopyBuildProvider.cs
- EntityAdapter.cs
- TraceContextRecord.cs
- IInstanceContextProvider.cs
- SpeakCompletedEventArgs.cs
- StringComparer.cs
- ResourcesGenerator.cs
- TextTreeObjectNode.cs
- TransformerTypeCollection.cs
- SystemKeyConverter.cs
- GenericUriParser.cs
- ScrollData.cs
- WizardForm.cs
- InternalConfigRoot.cs
- ObjectSelectorEditor.cs
- PeerApplicationLaunchInfo.cs
- BrowserCapabilitiesFactoryBase.cs
- FunctionDetailsReader.cs
- DataSourceView.cs
- GlyphingCache.cs
- MissingManifestResourceException.cs
- DesignerAttribute.cs