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
- SafeRightsManagementSessionHandle.cs
- ChildrenQuery.cs
- WmiInstallComponent.cs
- DiagnosticsConfigurationHandler.cs
- WriteStateInfoBase.cs
- WizardStepBase.cs
- NativeMethods.cs
- UserControl.cs
- GeometryHitTestResult.cs
- SqlReorderer.cs
- SqlRowUpdatingEvent.cs
- ForceCopyBuildProvider.cs
- PropertyIDSet.cs
- MTConfigUtil.cs
- SingleAnimationBase.cs
- OuterProxyWrapper.cs
- DataTransferEventArgs.cs
- SmiEventSink_DeferedProcessing.cs
- PrintPreviewControl.cs
- CompilerParameters.cs
- Wizard.cs
- TextEditorDragDrop.cs
- GiveFeedbackEvent.cs
- jithelpers.cs
- BufferedStream.cs
- SiteMapDataSource.cs
- LinqDataView.cs
- InvalidProgramException.cs
- IpcChannelHelper.cs
- DelegateOutArgument.cs
- ClientConfigurationSystem.cs
- UnknownBitmapEncoder.cs
- DesignOnlyAttribute.cs
- XPathDescendantIterator.cs
- Viewport3DVisual.cs
- SecureUICommand.cs
- ListViewGroup.cs
- ImageListStreamer.cs
- SoapSchemaImporter.cs
- DateTime.cs
- MdbDataFileEditor.cs
- VBCodeProvider.cs
- ellipse.cs
- CodeCommentStatementCollection.cs
- TokenBasedSetEnumerator.cs
- ConfigurationFileMap.cs
- XmlEncodedRawTextWriter.cs
- CollectionViewGroupRoot.cs
- CollectionConverter.cs
- WasAdminWrapper.cs
- VarInfo.cs
- RoleGroupCollection.cs
- EFDataModelProvider.cs
- XPathSelectionIterator.cs
- RIPEMD160Managed.cs
- String.cs
- DataServiceExpressionVisitor.cs
- SystemUdpStatistics.cs
- Confirm.cs
- SubstitutionList.cs
- AttachedPropertyMethodSelector.cs
- XmlBinaryReader.cs
- cookieexception.cs
- SQLResource.cs
- DbProviderFactories.cs
- InternalMappingException.cs
- UserNamePasswordValidator.cs
- CodeTypeConstructor.cs
- AnnotationHighlightLayer.cs
- COM2ExtendedUITypeEditor.cs
- LockedHandleGlyph.cs
- DynamicMethod.cs
- UriExt.cs
- InstancePersistence.cs
- ConfigPathUtility.cs
- TextEffectResolver.cs
- SiteMapPath.cs
- XmlSerializationWriter.cs
- HitTestParameters.cs
- TextFragmentEngine.cs
- ConfigXmlElement.cs
- IIS7UserPrincipal.cs
- XPathAncestorQuery.cs
- DispatcherBuilder.cs
- DecoderExceptionFallback.cs
- ComponentEditorForm.cs
- XamlWrappingReader.cs
- BackoffTimeoutHelper.cs
- LogicalTreeHelper.cs
- RuntimeConfig.cs
- EntityDataSourceDataSelectionPanel.cs
- diagnosticsswitches.cs
- X509ChainPolicy.cs
- AlternationConverter.cs
- InkCanvasSelection.cs
- SwitchElementsCollection.cs
- EdmItemCollection.cs
- XmlStreamNodeWriter.cs
- PostBackOptions.cs
- Label.cs