Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Runtime / InteropServices / GcHandle.cs / 1305376 / GcHandle.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== namespace System.Runtime.InteropServices { using System; using System.Security.Permissions; using System.Runtime.CompilerServices; using System.Threading; using System.Runtime.Versioning; using System.Diagnostics.Contracts; // These are the types of handles used by the EE. // IMPORTANT: These must match the definitions in ObjectHandle.h in the EE. // IMPORTANT: If new values are added to the enum the GCHandle::MaxHandleType // constant must be updated. [Serializable] [System.Runtime.InteropServices.ComVisible(true)] public enum GCHandleType { Weak = 0, WeakTrackResurrection = 1, Normal = 2, Pinned = 3 } // This class allows you to create an opaque, GC handle to any // COM+ object. A GC handle is used when an object reference must be // reachable from unmanaged memory. There are 3 kinds of roots: // Normal - keeps the object from being collected. // Weak - allows object to be collected and handle contents will be zeroed. // Weak references are zeroed before the finalizer runs, so if the // object is resurrected in the finalizer the weak reference is // still zeroed. // WeakTrackResurrection - Same as weak, but stays until after object is // really gone. // Pinned - same as normal, but allows the address of the actual object // to be taken. // [StructLayout(LayoutKind.Sequential)] [System.Runtime.InteropServices.ComVisible(true)] public struct GCHandle { // IMPORTANT: This must be kept in [....] with the GCHandleType enum. private const GCHandleType MaxHandleType = GCHandleType.Pinned; #if MDA_SUPPORTED [System.Security.SecuritySafeCritical] // auto-generated static GCHandle() { s_probeIsActive = Mda.IsInvalidGCHandleCookieProbeEnabled(); if (s_probeIsActive) s_cookieTable = new GCHandleCookieTable(); } #endif // Allocate a handle storing the object and the type. [System.Security.SecurityCritical] // auto-generated internal GCHandle(Object value, GCHandleType type) { // Make sure the type parameter is within the valid range for the enum. if ((uint)type > (uint)MaxHandleType) throw new ArgumentOutOfRangeException("type", Environment.GetResourceString("ArgumentOutOfRange_Enum")); Contract.EndContractBlock(); m_handle = InternalAlloc(value, type); // Record if the handle is pinned. if (type == GCHandleType.Pinned) SetIsPinned(); } // Used in the conversion functions below. [System.Security.SecurityCritical] // auto-generated internal GCHandle(IntPtr handle) { InternalCheckDomain(handle); m_handle = handle; } // Creates a new GC handle for an object. // // value - The object that the GC handle is created for. // type - The type of GC handle to create. // // returns a new GC handle that protects the object. [System.Security.SecurityCritical] // auto-generated_required public static GCHandle Alloc(Object value) { return new GCHandle(value, GCHandleType.Normal); } [System.Security.SecurityCritical] // auto-generated_required public static GCHandle Alloc(Object value, GCHandleType type) { return new GCHandle(value, type); } // Frees a GC handle. [System.Security.SecurityCritical] // auto-generated_required public void Free() { // Copy the handle instance member to a local variable. This is required to prevent // race conditions releasing the handle. IntPtr handle = m_handle; // Free the handle if it hasn't already been freed. if (handle != IntPtr.Zero && Interlocked.CompareExchange(ref m_handle, IntPtr.Zero, handle) == handle) { #if MDA_SUPPORTED // If this handle was passed out to unmanaged code, we need to remove it // from the cookie table. // NOTE: the entry in the cookie table must be released before the // internal handle is freed to prevent a race with reusing GC handles. if (s_probeIsActive) s_cookieTable.RemoveHandleIfPresent(handle); #endif #if WIN32 InternalFree((IntPtr)(((int)handle) & ~1)); #else InternalFree((IntPtr)(((long)handle) & ~1L)); #endif } else { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); } } // Target property - allows getting / updating of the handle's referent. public Object Target { [System.Security.SecurityCritical] // auto-generated_required get { // Check if the handle was never initialized or was freed. if (m_handle == IntPtr.Zero) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); return InternalGet(GetHandleValue()); } [System.Security.SecurityCritical] // auto-generated_required set { // Check if the handle was never initialized or was freed. if (m_handle == IntPtr.Zero) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); InternalSet(GetHandleValue(), value, IsPinned()); } } // Retrieve the address of an object in a Pinned handle. This throws // an exception if the handle is any type other than Pinned. [System.Security.SecurityCritical] // auto-generated_required public IntPtr AddrOfPinnedObject() { // Check if the handle was not a pinned handle. if (!IsPinned()) { // Check if the handle was never initialized for was freed. if (m_handle == IntPtr.Zero) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); // You can only get the address of pinned handles. throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotPinned")); } // Get the address. return InternalAddrOfPinnedObject(GetHandleValue()); } // Determine whether this handle has been allocated or not. public bool IsAllocated { get { return m_handle != IntPtr.Zero; } } // Used to create a GCHandle from an int. This is intended to // be used with the reverse conversion. [System.Security.SecurityCritical] // auto-generated_required public static explicit operator GCHandle(IntPtr value) { return FromIntPtr(value); } [System.Security.SecurityCritical] // auto-generated_required public static GCHandle FromIntPtr(IntPtr value) { if (value == IntPtr.Zero) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); Contract.EndContractBlock(); IntPtr handle = value; #if MDA_SUPPORTED if (s_probeIsActive) { // Make sure this cookie matches up with a GCHandle we've passed out a cookie for. handle = s_cookieTable.GetHandle(value); if (IntPtr.Zero == handle) { // Fire an MDA if we were unable to retrieve the GCHandle. Mda.FireInvalidGCHandleCookieProbe(value); return new GCHandle(IntPtr.Zero); } } #endif return new GCHandle(handle); } // Used to get the internal integer representation of the handle out. public static explicit operator IntPtr(GCHandle value) { return ToIntPtr(value); } public static IntPtr ToIntPtr(GCHandle value) { #if MDA_SUPPORTED if (s_probeIsActive) { // Remember that we passed this GCHandle out by storing the cookie we returned so we // can later validate. return s_cookieTable.FindOrAddHandle(value.m_handle); } #endif return value.m_handle; } public override int GetHashCode() { return m_handle.GetHashCode(); } public override bool Equals(Object o) { GCHandle hnd; // Check that o is a GCHandle first if(o == null || !(o is GCHandle)) return false; else hnd = (GCHandle) o; return m_handle == hnd.m_handle; } public static bool operator ==(GCHandle a, GCHandle b) { return a.m_handle == b.m_handle; } public static bool operator !=(GCHandle a, GCHandle b) { return a.m_handle != b.m_handle; } internal IntPtr GetHandleValue() { #if WIN32 return new IntPtr(((int)m_handle) & ~1); #else return new IntPtr(((long)m_handle) & ~1L); #endif } internal bool IsPinned() { #if WIN32 return (((int)m_handle) & 1) != 0; #else return (((long)m_handle) & 1) != 0; #endif } internal void SetIsPinned() { #if WIN32 m_handle = new IntPtr(((int)m_handle) | 1); #else m_handle = new IntPtr(((long)m_handle) | 1L); #endif } // Internal native calls that this implementation uses. [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] [ResourceExposure(ResourceScope.None)] internal static extern IntPtr InternalAlloc(Object value, GCHandleType type); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void InternalFree(IntPtr handle); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern Object InternalGet(IntPtr handle); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void InternalSet(IntPtr handle, Object value, bool isPinned); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern Object InternalCompareExchange(IntPtr handle, Object value, Object oldValue, bool isPinned); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern IntPtr InternalAddrOfPinnedObject(IntPtr handle); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void InternalCheckDomain(IntPtr handle); // The actual integer handle value that the EE uses internally. private IntPtr m_handle; #if MDA_SUPPORTED // The GCHandle cookie table. static private GCHandleCookieTable s_cookieTable = null; static private bool s_probeIsActive = false; #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== namespace System.Runtime.InteropServices { using System; using System.Security.Permissions; using System.Runtime.CompilerServices; using System.Threading; using System.Runtime.Versioning; using System.Diagnostics.Contracts; // These are the types of handles used by the EE. // IMPORTANT: These must match the definitions in ObjectHandle.h in the EE. // IMPORTANT: If new values are added to the enum the GCHandle::MaxHandleType // constant must be updated. [Serializable] [System.Runtime.InteropServices.ComVisible(true)] public enum GCHandleType { Weak = 0, WeakTrackResurrection = 1, Normal = 2, Pinned = 3 } // This class allows you to create an opaque, GC handle to any // COM+ object. A GC handle is used when an object reference must be // reachable from unmanaged memory. There are 3 kinds of roots: // Normal - keeps the object from being collected. // Weak - allows object to be collected and handle contents will be zeroed. // Weak references are zeroed before the finalizer runs, so if the // object is resurrected in the finalizer the weak reference is // still zeroed. // WeakTrackResurrection - Same as weak, but stays until after object is // really gone. // Pinned - same as normal, but allows the address of the actual object // to be taken. // [StructLayout(LayoutKind.Sequential)] [System.Runtime.InteropServices.ComVisible(true)] public struct GCHandle { // IMPORTANT: This must be kept in [....] with the GCHandleType enum. private const GCHandleType MaxHandleType = GCHandleType.Pinned; #if MDA_SUPPORTED [System.Security.SecuritySafeCritical] // auto-generated static GCHandle() { s_probeIsActive = Mda.IsInvalidGCHandleCookieProbeEnabled(); if (s_probeIsActive) s_cookieTable = new GCHandleCookieTable(); } #endif // Allocate a handle storing the object and the type. [System.Security.SecurityCritical] // auto-generated internal GCHandle(Object value, GCHandleType type) { // Make sure the type parameter is within the valid range for the enum. if ((uint)type > (uint)MaxHandleType) throw new ArgumentOutOfRangeException("type", Environment.GetResourceString("ArgumentOutOfRange_Enum")); Contract.EndContractBlock(); m_handle = InternalAlloc(value, type); // Record if the handle is pinned. if (type == GCHandleType.Pinned) SetIsPinned(); } // Used in the conversion functions below. [System.Security.SecurityCritical] // auto-generated internal GCHandle(IntPtr handle) { InternalCheckDomain(handle); m_handle = handle; } // Creates a new GC handle for an object. // // value - The object that the GC handle is created for. // type - The type of GC handle to create. // // returns a new GC handle that protects the object. [System.Security.SecurityCritical] // auto-generated_required public static GCHandle Alloc(Object value) { return new GCHandle(value, GCHandleType.Normal); } [System.Security.SecurityCritical] // auto-generated_required public static GCHandle Alloc(Object value, GCHandleType type) { return new GCHandle(value, type); } // Frees a GC handle. [System.Security.SecurityCritical] // auto-generated_required public void Free() { // Copy the handle instance member to a local variable. This is required to prevent // race conditions releasing the handle. IntPtr handle = m_handle; // Free the handle if it hasn't already been freed. if (handle != IntPtr.Zero && Interlocked.CompareExchange(ref m_handle, IntPtr.Zero, handle) == handle) { #if MDA_SUPPORTED // If this handle was passed out to unmanaged code, we need to remove it // from the cookie table. // NOTE: the entry in the cookie table must be released before the // internal handle is freed to prevent a race with reusing GC handles. if (s_probeIsActive) s_cookieTable.RemoveHandleIfPresent(handle); #endif #if WIN32 InternalFree((IntPtr)(((int)handle) & ~1)); #else InternalFree((IntPtr)(((long)handle) & ~1L)); #endif } else { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); } } // Target property - allows getting / updating of the handle's referent. public Object Target { [System.Security.SecurityCritical] // auto-generated_required get { // Check if the handle was never initialized or was freed. if (m_handle == IntPtr.Zero) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); return InternalGet(GetHandleValue()); } [System.Security.SecurityCritical] // auto-generated_required set { // Check if the handle was never initialized or was freed. if (m_handle == IntPtr.Zero) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); InternalSet(GetHandleValue(), value, IsPinned()); } } // Retrieve the address of an object in a Pinned handle. This throws // an exception if the handle is any type other than Pinned. [System.Security.SecurityCritical] // auto-generated_required public IntPtr AddrOfPinnedObject() { // Check if the handle was not a pinned handle. if (!IsPinned()) { // Check if the handle was never initialized for was freed. if (m_handle == IntPtr.Zero) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); // You can only get the address of pinned handles. throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotPinned")); } // Get the address. return InternalAddrOfPinnedObject(GetHandleValue()); } // Determine whether this handle has been allocated or not. public bool IsAllocated { get { return m_handle != IntPtr.Zero; } } // Used to create a GCHandle from an int. This is intended to // be used with the reverse conversion. [System.Security.SecurityCritical] // auto-generated_required public static explicit operator GCHandle(IntPtr value) { return FromIntPtr(value); } [System.Security.SecurityCritical] // auto-generated_required public static GCHandle FromIntPtr(IntPtr value) { if (value == IntPtr.Zero) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized")); Contract.EndContractBlock(); IntPtr handle = value; #if MDA_SUPPORTED if (s_probeIsActive) { // Make sure this cookie matches up with a GCHandle we've passed out a cookie for. handle = s_cookieTable.GetHandle(value); if (IntPtr.Zero == handle) { // Fire an MDA if we were unable to retrieve the GCHandle. Mda.FireInvalidGCHandleCookieProbe(value); return new GCHandle(IntPtr.Zero); } } #endif return new GCHandle(handle); } // Used to get the internal integer representation of the handle out. public static explicit operator IntPtr(GCHandle value) { return ToIntPtr(value); } public static IntPtr ToIntPtr(GCHandle value) { #if MDA_SUPPORTED if (s_probeIsActive) { // Remember that we passed this GCHandle out by storing the cookie we returned so we // can later validate. return s_cookieTable.FindOrAddHandle(value.m_handle); } #endif return value.m_handle; } public override int GetHashCode() { return m_handle.GetHashCode(); } public override bool Equals(Object o) { GCHandle hnd; // Check that o is a GCHandle first if(o == null || !(o is GCHandle)) return false; else hnd = (GCHandle) o; return m_handle == hnd.m_handle; } public static bool operator ==(GCHandle a, GCHandle b) { return a.m_handle == b.m_handle; } public static bool operator !=(GCHandle a, GCHandle b) { return a.m_handle != b.m_handle; } internal IntPtr GetHandleValue() { #if WIN32 return new IntPtr(((int)m_handle) & ~1); #else return new IntPtr(((long)m_handle) & ~1L); #endif } internal bool IsPinned() { #if WIN32 return (((int)m_handle) & 1) != 0; #else return (((long)m_handle) & 1) != 0; #endif } internal void SetIsPinned() { #if WIN32 m_handle = new IntPtr(((int)m_handle) | 1); #else m_handle = new IntPtr(((long)m_handle) | 1L); #endif } // Internal native calls that this implementation uses. [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] [ResourceExposure(ResourceScope.None)] internal static extern IntPtr InternalAlloc(Object value, GCHandleType type); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void InternalFree(IntPtr handle); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern Object InternalGet(IntPtr handle); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void InternalSet(IntPtr handle, Object value, bool isPinned); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern Object InternalCompareExchange(IntPtr handle, Object value, Object oldValue, bool isPinned); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern IntPtr InternalAddrOfPinnedObject(IntPtr handle); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void InternalCheckDomain(IntPtr handle); // The actual integer handle value that the EE uses internally. private IntPtr m_handle; #if MDA_SUPPORTED // The GCHandle cookie table. static private GCHandleCookieTable s_cookieTable = null; static private bool s_probeIsActive = false; #endif } } // 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
- RelatedEnd.cs
- NodeFunctions.cs
- ImageMapEventArgs.cs
- XmlDocumentSchema.cs
- PolicyException.cs
- DrawItemEvent.cs
- Point4DConverter.cs
- CodeBinaryOperatorExpression.cs
- UserControlParser.cs
- BitmapEffectInput.cs
- StateMachineSubscriptionManager.cs
- BatchWriter.cs
- BevelBitmapEffect.cs
- SafeRightsManagementHandle.cs
- _AutoWebProxyScriptEngine.cs
- ListInitExpression.cs
- DataTable.cs
- NamespaceQuery.cs
- BitmapEffectInput.cs
- RectangleGeometry.cs
- DataColumnMapping.cs
- DiscoveryProxy.cs
- DesignerAttribute.cs
- OleDbStruct.cs
- DataGridColumnDropSeparator.cs
- Substitution.cs
- Splitter.cs
- LicenseException.cs
- ClrProviderManifest.cs
- EntryIndex.cs
- DynamicPhysicalDiscoSearcher.cs
- FrameworkTextComposition.cs
- SqlRowUpdatedEvent.cs
- MenuItemAutomationPeer.cs
- Char.cs
- HotSpotCollection.cs
- TemplateControlParser.cs
- Window.cs
- QuaternionAnimationBase.cs
- UIElementAutomationPeer.cs
- RequestDescription.cs
- FloatUtil.cs
- FastEncoderWindow.cs
- MissingSatelliteAssemblyException.cs
- DataService.cs
- XamlWrappingReader.cs
- InkPresenter.cs
- SecurityAlgorithmSuite.cs
- Propagator.JoinPropagator.cs
- CompareValidator.cs
- serverconfig.cs
- UpdateProgress.cs
- ItemPager.cs
- BodyGlyph.cs
- DropShadowBitmapEffect.cs
- WindowsGraphicsCacheManager.cs
- WSMessageEncoding.cs
- BitArray.cs
- RepeaterDesigner.cs
- SmiConnection.cs
- CachedTypeface.cs
- OleDbCommandBuilder.cs
- DataGridViewLinkColumn.cs
- ConsoleTraceListener.cs
- WorkflowOwnershipException.cs
- ListCollectionView.cs
- RegexMatch.cs
- VisualTreeHelper.cs
- UnsafeNativeMethodsTablet.cs
- MimeParameterWriter.cs
- EntityDataSourceColumn.cs
- ThreadNeutralSemaphore.cs
- TdsParameterSetter.cs
- autovalidator.cs
- DictionaryKeyPropertyAttribute.cs
- ContextMarshalException.cs
- BamlCollectionHolder.cs
- DuplexChannel.cs
- TemplateXamlTreeBuilder.cs
- SiteMap.cs
- NodeLabelEditEvent.cs
- UITypeEditor.cs
- ContentFileHelper.cs
- NewArrayExpression.cs
- StateManagedCollection.cs
- UserControl.cs
- DbDataSourceEnumerator.cs
- Barrier.cs
- CollectionChangedEventManager.cs
- Tile.cs
- _PooledStream.cs
- OptimalBreakSession.cs
- NavigatorInput.cs
- StringValidator.cs
- TraceUtility.cs
- TextControl.cs
- ZipIOExtraFieldZip64Element.cs
- UriGenerator.cs
- ToolZone.cs
- XmlExtensionFunction.cs