Code:
/ FX-1434 / FX-1434 / 1.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
- ContextStack.cs
- TableRowCollection.cs
- AuthStoreRoleProvider.cs
- DrawListViewItemEventArgs.cs
- MetadataWorkspace.cs
- Exceptions.cs
- infer.cs
- QueryCacheManager.cs
- IsolatedStoragePermission.cs
- XmlSchemaObjectCollection.cs
- RootNamespaceAttribute.cs
- EncoderFallback.cs
- SimpleBitVector32.cs
- MaskDescriptors.cs
- EventLogEntryCollection.cs
- ElementNotEnabledException.cs
- DeclarativeCatalogPartDesigner.cs
- Italic.cs
- TypeConverterMarkupExtension.cs
- DbParameterHelper.cs
- ThicknessAnimationBase.cs
- TabPanel.cs
- Debug.cs
- SystemSounds.cs
- ProcessThread.cs
- WindowsRichEdit.cs
- Validator.cs
- ViewCellSlot.cs
- DefaultParameterValueAttribute.cs
- DataGridViewColumnStateChangedEventArgs.cs
- DesignerFrame.cs
- LostFocusEventManager.cs
- ReflectPropertyDescriptor.cs
- ConfigXmlAttribute.cs
- RawKeyboardInputReport.cs
- TemplateParser.cs
- Debug.cs
- DataSvcMapFileSerializer.cs
- WpfMemberInvoker.cs
- TransformerConfigurationWizardBase.cs
- SettingsPropertyNotFoundException.cs
- Regex.cs
- DynamicPropertyReader.cs
- RichTextBox.cs
- IProvider.cs
- RequestValidator.cs
- XPathNodeHelper.cs
- QilFactory.cs
- EdmItemCollection.OcAssemblyCache.cs
- DetailsViewPagerRow.cs
- DataGridViewControlCollection.cs
- UnmanagedMarshal.cs
- ThreadExceptionEvent.cs
- AppDomainManager.cs
- FontSource.cs
- StreamedWorkflowDefinitionContext.cs
- PenThreadPool.cs
- HttpHandlersSection.cs
- DataStorage.cs
- ComponentDispatcher.cs
- MouseActionValueSerializer.cs
- Evaluator.cs
- Attributes.cs
- MetadataArtifactLoaderComposite.cs
- RuntimeIdentifierPropertyAttribute.cs
- Transform3DCollection.cs
- TouchEventArgs.cs
- SymmetricKeyWrap.cs
- LocalizableAttribute.cs
- UnsafeNativeMethods.cs
- WriteTimeStream.cs
- SQLByteStorage.cs
- Visual3D.cs
- ProcessHostServerConfig.cs
- RectAnimationClockResource.cs
- SettingsSection.cs
- TextSerializer.cs
- Internal.cs
- WorkflowMarkupSerializerMapping.cs
- ThicknessAnimationBase.cs
- SimpleWorkerRequest.cs
- ThemeDirectoryCompiler.cs
- CssStyleCollection.cs
- HtmlUtf8RawTextWriter.cs
- SignatureHelper.cs
- Hash.cs
- HashStream.cs
- AuthenticationModeHelper.cs
- Matrix3DStack.cs
- DataAdapter.cs
- GeometryModel3D.cs
- Msmq4PoisonHandler.cs
- EndOfStreamException.cs
- HostProtectionPermission.cs
- MultipartIdentifier.cs
- RegexTypeEditor.cs
- ViewSimplifier.cs
- XmlSchemaNotation.cs
- __ConsoleStream.cs
- AutomationPeer.cs