Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Threading / HostExecutionContextManager.cs / 1 / HostExecutionContextManager.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
/*============================================================
**
** Class: ExecutionContext
**
**
** Purpose: Capture Host execution context for a thread
**
**
===========================================================*/
namespace System.Threading
{
using System.Security;
using System.Runtime.Remoting;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
internal class HostExecutionContextSwitcher
{
internal ExecutionContext executionContext;
internal HostExecutionContext previousHostContext;
internal HostExecutionContext currentHostContext;
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
static public void Undo(Object switcherObject)
{
if (switcherObject == null)
return;
// otherwise call the host
HostExecutionContextManager hostMgr = HostExecutionContextManager.GetCurrentHostExecutionContextManager();
if (hostMgr != null)
{
hostMgr.Revert(switcherObject);
}
}
}
public class HostExecutionContext
{
private Object state;
protected internal Object State {
get {
return state;
}
set {
state = value;
}
}
public HostExecutionContext()
{
}
public HostExecutionContext(Object state)
{
this.state = state;
}
public virtual HostExecutionContext CreateCopy()
{
Object newState = state;
if (state is IUnknownSafeHandle)
{
// Clone the IUnknown handle
newState = ((IUnknownSafeHandle)state).Clone();
}
return new HostExecutionContext(state);
}
}
internal class IUnknownSafeHandle : SafeHandle
{
public IUnknownSafeHandle() : base(IntPtr.Zero, true)
{
}
public override bool IsInvalid {
get { return handle == IntPtr.Zero; }
}
override protected bool ReleaseHandle()
{
HostExecutionContextManager.ReleaseHostSecurityContext(this.handle);
return true;
}
internal Object Clone()
{
IUnknownSafeHandle unkSafeHandleCloned = new IUnknownSafeHandle();
// call into the Hosting API to CLONE the host context
// stores the output IUnknown in the safehandle,
if (!IsInvalid)
{
HostExecutionContextManager.CloneHostSecurityContext(this, unkSafeHandleCloned);
}
return unkSafeHandleCloned;
}
}
public class HostExecutionContextManager
{
private static bool _fIsHostedChecked;
private static bool _fIsHosted;
private static HostExecutionContextManager _hostExecutionContextManager;
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static private extern bool HostSecurityManagerPresent();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern int ReleaseHostSecurityContext(IntPtr context);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern int CloneHostSecurityContext(SafeHandle context, SafeHandle clonedContext);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static private extern int CaptureHostSecurityContext(SafeHandle capturedContext);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static private extern int SetHostSecurityContext(SafeHandle context, bool fReturnPrevious, SafeHandle prevContext);
internal static bool CheckIfHosted()
{
if (!_fIsHostedChecked)
{
_fIsHosted = HostSecurityManagerPresent();
_fIsHostedChecked = true;
}
return _fIsHosted;
}
// capture Host SecurityContext
public virtual HostExecutionContext Capture()
{
HostExecutionContext context = null;
// check if we are hosted
if (CheckIfHosted())
{
IUnknownSafeHandle unkSafeHandle = new IUnknownSafeHandle();
context = new HostExecutionContext(unkSafeHandle);
// call into the Hosting API to capture the host context
// stores the output IUnknown in the safehandle,
CaptureHostSecurityContext(unkSafeHandle);
}
// otherwise
return context;
}
// Set Host SecurityContext
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
public virtual Object SetHostExecutionContext(HostExecutionContext hostExecutionContext)
{
if (hostExecutionContext == null)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotNewCaptureContext"));
}
HostExecutionContextSwitcher switcher = new HostExecutionContextSwitcher();
ExecutionContext currentExecutionContext = Thread.CurrentThread.ExecutionContext;
switcher.executionContext = currentExecutionContext;
switcher.currentHostContext = hostExecutionContext;
switcher.previousHostContext = null;
if (CheckIfHosted())
{
if (hostExecutionContext.State is IUnknownSafeHandle)
{
// setup the previous unknown handle
IUnknownSafeHandle unkPrevSafeHandle = new IUnknownSafeHandle();
switcher.previousHostContext = new HostExecutionContext(unkPrevSafeHandle);
// get the current handle
IUnknownSafeHandle unkSafeHandle = (IUnknownSafeHandle)hostExecutionContext.State;
// call into the Hosting API to set the host context
// second arg indicates whether we want to retrieve the previous context
SetHostSecurityContext(unkSafeHandle,true,unkPrevSafeHandle);
}
}
// store the current HostExecutionContext in the ExecutionContext.
currentExecutionContext.HostExecutionContext = hostExecutionContext;
return switcher;
}
// this method needs to be reliable
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure),
ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public virtual void Revert(Object previousState)
{
HostExecutionContextSwitcher hostContextSwitcher = previousState as HostExecutionContextSwitcher;
if (hostContextSwitcher == null)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotOverrideSetWithoutRevert"));
}
// check Undo is happening on the correct thread
ExecutionContext executionContext = Thread.CurrentThread.ExecutionContext;
if (executionContext != hostContextSwitcher.executionContext)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseSwitcherOtherThread"));
}
hostContextSwitcher.executionContext = null; // Make sure switcher cannot be re-used.
HostExecutionContext revertFromHostContext = executionContext.HostExecutionContext;
// if the current host context is not the same as the one in the switcher, then revert is being called out of order
if (revertFromHostContext != hostContextSwitcher.currentHostContext)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseSwitcherOtherThread"));
}
// get the previous host context
HostExecutionContext revertToHostContext = hostContextSwitcher.previousHostContext;
// now check if we are hosted and revert the context in the host
if (CheckIfHosted())
{
// try restore the previous context as the current context
if (revertToHostContext != null && revertToHostContext.State is IUnknownSafeHandle)
{
IUnknownSafeHandle unkprevSafeHandle = (IUnknownSafeHandle)revertToHostContext.State;
// call into the Hosting API to set the host context
SetHostSecurityContext(unkprevSafeHandle, false, null);
}
}
//restore the previous host context in the executioncontext
executionContext.HostExecutionContext = revertToHostContext;
}
internal static HostExecutionContext CaptureHostExecutionContext()
{
HostExecutionContext hostContext = null;
// capture the host execution context
HostExecutionContextManager hostMgr = HostExecutionContextManager.GetCurrentHostExecutionContextManager();
if (hostMgr != null)
{
hostContext = hostMgr.Capture();
}
return hostContext;
}
internal static Object SetHostExecutionContextInternal(HostExecutionContext hostContext)
{
HostExecutionContextManager hostMgr = HostExecutionContextManager.GetCurrentHostExecutionContextManager();
Object switcher = null;
if (hostMgr != null)
{
switcher = hostMgr.SetHostExecutionContext(hostContext);
//
}
return switcher;
}
// retun the HostExecutionContextManager for the current AppDomain
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal static HostExecutionContextManager GetCurrentHostExecutionContextManager()
{
// this is called during AppDomainManager initialization, this is a thread safe place
// to setup the HostExecutionContextManager for the current AppDomain
if (AppDomainManager.CurrentAppDomainManager != null) {
return AppDomainManager.CurrentAppDomainManager.HostExecutionContextManager;
}
return null;
}
// retun the HostExecutionContextManager for the current AppDomain
internal static HostExecutionContextManager GetInternalHostExecutionContextManager()
{
if (_hostExecutionContextManager == null) {
// setup the HostExecutionContextManager for the current AppDomain
BCLDebug.Assert(_hostExecutionContextManager == null, "HostExecutionContextManager should be null");
_hostExecutionContextManager = new HostExecutionContextManager();
}
return _hostExecutionContextManager;
}
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Function.cs
- XmlElement.cs
- ExtensionSimplifierMarkupObject.cs
- TraceHandlerErrorFormatter.cs
- CheckBoxStandardAdapter.cs
- Fx.cs
- TransformCryptoHandle.cs
- TypeGeneratedEventArgs.cs
- MultiAsyncResult.cs
- MediaContext.cs
- KerberosTicketHashIdentifierClause.cs
- WS2007FederationHttpBindingCollectionElement.cs
- FormatterServicesNoSerializableCheck.cs
- XMLSyntaxException.cs
- ManualWorkflowSchedulerService.cs
- TabletCollection.cs
- ResolvedKeyFrameEntry.cs
- ServiceRouteHandler.cs
- WmlLabelAdapter.cs
- ComplexType.cs
- EndCreateSecurityTokenRequest.cs
- DocumentApplicationJournalEntry.cs
- CultureInfoConverter.cs
- TableLayout.cs
- datacache.cs
- ZipIOExtraField.cs
- HttpValueCollection.cs
- coordinator.cs
- SafeArrayTypeMismatchException.cs
- SurrogateSelector.cs
- WindowsListViewSubItem.cs
- QueryableDataSource.cs
- PermissionSetTriple.cs
- ProcessModule.cs
- ViewLoader.cs
- MenuItemAutomationPeer.cs
- HttpCookieCollection.cs
- CodeDelegateCreateExpression.cs
- UnsafePeerToPeerMethods.cs
- TypeToken.cs
- DbConnectionPoolOptions.cs
- MulticastIPAddressInformationCollection.cs
- DependencyPropertyDescriptor.cs
- Rect.cs
- PropertyGeneratedEventArgs.cs
- BaseValidator.cs
- OrderedEnumerableRowCollection.cs
- HtmlToClrEventProxy.cs
- XmlSchemaAttribute.cs
- LingerOption.cs
- Win32Exception.cs
- SemaphoreSecurity.cs
- LocalizabilityAttribute.cs
- AdditionalEntityFunctions.cs
- Visitor.cs
- TypeDefinition.cs
- BamlResourceSerializer.cs
- IItemProperties.cs
- CustomValidator.cs
- ThicknessAnimation.cs
- Int32.cs
- TTSEvent.cs
- InternalRelationshipCollection.cs
- StatusBarPanel.cs
- XmlSchemaSimpleContentExtension.cs
- CacheSection.cs
- IResourceProvider.cs
- SessionIDManager.cs
- EntityDataSourceWizardForm.cs
- XmlChoiceIdentifierAttribute.cs
- Parallel.cs
- ServiceContractViewControl.cs
- DataBindingCollection.cs
- TransformDescriptor.cs
- WhitespaceRuleLookup.cs
- ClassDataContract.cs
- ValidatedMobileControlConverter.cs
- _Connection.cs
- ViewStateModeByIdAttribute.cs
- Interlocked.cs
- SHA1CryptoServiceProvider.cs
- PropertyItem.cs
- ToolBarPanel.cs
- BrowserCapabilitiesFactory35.cs
- TextRangeEdit.cs
- _FtpDataStream.cs
- InvalidOleVariantTypeException.cs
- SqlDataSourceWizardForm.cs
- ExpressionDumper.cs
- FlowPanelDesigner.cs
- XamlToRtfWriter.cs
- KeyboardNavigation.cs
- UIElementIsland.cs
- TextPointerBase.cs
- GridViewColumn.cs
- ZoneButton.cs
- FontUnit.cs
- DataObjectPastingEventArgs.cs
- SimpleWorkerRequest.cs
- SqlMethodAttribute.cs