惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - Franky
MyScale Blog
MyScale Blog
A
About on SuperTechFans
博客园_首页
B
Blog RSS Feed
Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Vercel News
Vercel News
C
Check Point Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 【当耐特】
M
MIT News - Artificial intelligence
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
I
InfoQ
罗磊的独立博客

博客园 - wanna

不知是不是年纪大了,常想起博客园,博客堂的旧事.博客堂好像不再存在了,博客园经营的越红火了.还记得这些人,早期的大牛人? 希望新一年会是和平的一年 js类成员笔记 Create your own HttpContext class>> from 123aspx.net mssql keyword,statements Transact-SQL Optimization Tips ..from mssqlcity.com ASP.NET's Data Storage Objects 通过AOP提高代码的封装和可复用性 Tomcat 与 IIS 整合[转] 如果获取一个表列的最大值.. - wanna - 博客园 无法阻止的弹出窗口: - wanna - 博客园 Attribute C#的Random类的源码 Regex.cs C#的GUID是怎么样生成的 Ms的DateTime类源码 Ms的Calendar源码 MS的string.cs MS公开的gc.cs源码
MS公开的gchandle.cs源码
wanna · 2005-08-04 · via 博客园 - wanna

  1// ==++==
  2// 
  3//   
  4//    Copyright (c) 2002 Microsoft Corporation.  All rights reserved.
  5//   
  6//    The use and distribution terms for this software are contained in the file
  7//    named license.txt, which can be found in the root of this distribution.
  8//    By using this software in any fashion, you are agreeing to be bound by the
  9//    terms of this license.
 10//   
 11//    You must not remove this notice, or any other, from this software.
 12//   
 13// 
 14// ==--==
 15namespace System.Runtime.InteropServices {
 16    
 17 using System;
 18 using System.Security.Permissions;
 19 using System.Runtime.CompilerServices;
 20
 21 // These are the types of handles used by the EE.  IMPORTANT: These must
 22 // match the definitions in ObjectHandle.h in the EE.
 23 /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType"]/*' />
 24 [Serializable]
 25 public enum GCHandleType
 26 {
 27  /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType.Weak"]/*' />
 28  Weak = 0,
 29  /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType.WeakTrackResurrection"]/*' />
 30  WeakTrackResurrection = 1,
 31  /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType.Normal"]/*' />
 32  Normal = 2,
 33  /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType.Pinned"]/*' />
 34  Pinned = 3
 35 }

 36
 37    // This class allows you to create an opaque, GC handle to any 
 38    // COM+ object. A GC handle is used when an object reference must be
 39 // reachable from unmanaged memory.  There are 3 kinds of roots:
 40 // Normal - keeps the object from being collected.
 41 // Weak - allows object to be collected and handle contents will be zeroed.
 42    //          Weak references are zeroed before the finalizer runs, so if the
 43    //          object is resurrected in the finalizer the weak reference is
 44    //          still zeroed.
 45 // WeakTrackResurrection - Same as weak, but stays until after object is
 46    //          really gone.
 47 // Pinned - same as normal, but allows the address of the actual object
 48 //          to be taken.
 49    //
 50    /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle"]/*' />
 51 [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
 52    public struct GCHandle
 53    {
 54        // Allocate a handle storing the object and the type.
 55        internal GCHandle(Object value, GCHandleType type)
 56  {
 57   m_handle = InternalAlloc(value, type);
 58
 59   // Record if the handle is pinned.
 60   if (type == GCHandleType.Pinned)
 61                SetIsPinned();
 62  }
  
 63
 64  // Used in the conversion functions below.
 65  internal GCHandle(IntPtr handle)
 66  {
 67         InternalCheckDomain(handle);
 68   m_handle = handle;
 69  }

 70
 71        // Creates a new GC handle for an object.
 72        //
 73        // value - The object that the GC handle is created for.
 74  // type - The type of GC handle to create.
 75        // 
 76     // returns a new GC handle that protects the object.
 77        /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.Alloc"]/*' />
 78        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
 79        public static GCHandle Alloc(Object value)
 80        {
 81   return new GCHandle(value, GCHandleType.Normal);
 82        }

 83
 84        /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.Alloc1"]/*' />
 85        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
 86        public static GCHandle Alloc(Object value, GCHandleType type)
 87        {
 88   return new GCHandle(value, type);
 89        }

 90
 91        // Frees a GC handle.  The caller must provide synchronization to
 92  // prevent multiple threads from executing this simultaneously for
 93  // a given handle. If you modify this method please modify the 
 94        // __InternalFree also which is the internal without the linktime check.
 95        /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.Free"]/*' />
 96        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
 97        public void Free()
 98  {
 99   // Check if the handle was never initialized for was freed.
100   if (m_handle == IntPtr.Zero)
101    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
102
103   // Free the handle.
104   InternalFree(GetHandleValue());
105   m_handle = IntPtr.Zero;
106  }

107  
108  internal void __InternalFree()
109  {
110   // Check if the handle was never initialized for was freed.
111   if (m_handle == IntPtr.Zero)
112    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
113
114   // Free the handle.
115   InternalFree(GetHandleValue());
116   m_handle = IntPtr.Zero;
117  }

118
119        // Target property - allows getting / updating of the handle's referent. If you modify this method
120
121        // then modify the __InternalTarget too which is the internal method without the linktime check.
122        /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.Target"]/*' />
123        public Object Target
124        {
125         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
126            get
127            {
128                // Check if the handle was never initialized or was freed.
129    if (m_handle == IntPtr.Zero)
130     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
131
132                return InternalGet(GetHandleValue());
133            }

134    
135         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
136            set
137            {
138                // Check if the handle was never initialized or was freed.
139    if (m_handle == IntPtr.Zero)
140     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
141
142                InternalSet(GetHandleValue(), value, IsPinned());
143            }

144        }

145        
146        internal Object __InternalTarget
147        {
148            get
149            {
150                // Check if the handle was never initialized or was freed.
151    if (m_handle == IntPtr.Zero)
152     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
153
154                return InternalGet(GetHandleValue());
155            }

156        }

157
158        // Retrieve the address of an object in a Pinned handle.  This throws
159  // an exception if the handle is any type other than Pinned.
160  /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.AddrOfPinnedObject"]/*' />
161        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
162  public IntPtr AddrOfPinnedObject()
163  {
164   // Check if the handle was not a pinned handle.
165   if (!IsPinned())
166   {
167    // Check if the handle was never initialized for was freed.
168    if (m_handle == IntPtr.Zero)
169     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
170
171    // You can only get the address of pinned handles.
172    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotPinned"));
173   }

174
175   // Get the address.
176   return InternalAddrOfPinnedObject(GetHandleValue());
177  }

178
179        // Determine whether this handle has been allocated or not.
180  /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.IsAllocated"]/*' />
181  public bool IsAllocated
182  {
183   get
184   {
185    return m_handle != IntPtr.Zero;
186   }

187  }

188
189        // Used to create a GCHandle from an int.  This is intended to
190  // be used with the reverse conversion.
191     /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.operatorGCHandle"]/*' />
192        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
193     public static explicit operator GCHandle(IntPtr value)
194  {
195            return new GCHandle(value);
196        }

197
198 // Used to get the internal integer representation of the handle out.
199     /// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.operatorIntPtr"]/*' />
200     public static explicit operator IntPtr(GCHandle value)
201  {
202            return value.m_handle;
203        }

204
205        internal IntPtr GetHandleValue()
206        {
207#if WIN32
208            return new IntPtr(((int)m_handle) & ~1);
209#else
210            return new IntPtr(((long)m_handle) & ~1L);
211#endif
212        }

213
214        internal bool IsPinned()
215        {
216#if WIN32
217            return (((int)m_handle) & 1!= 0;
218#else
219            return (((long)m_handle) & 1!= 0;
220#endif
221        }

222
223        internal void SetIsPinned()
224        {
225#if WIN32
226            m_handle = new IntPtr(((int)m_handle) | 1);
227#else
228            m_handle = new IntPtr(((long)m_handle) | 1L);
229#endif
230        }

231
232  // Internal native calls that this implementation uses.
233        [MethodImplAttribute(MethodImplOptions.InternalCall)]
234  internal static extern IntPtr InternalAlloc(Object value, GCHandleType type);
235        [MethodImplAttribute(MethodImplOptions.InternalCall)]
236        internal static extern void InternalFree(IntPtr handle);
237        [MethodImplAttribute(MethodImplOptions.InternalCall)]
238        internal static extern Object InternalGet(IntPtr handle);
239        [MethodImplAttribute(MethodImplOptions.InternalCall)]
240        internal static extern void InternalSet(IntPtr handle, Object value, bool isPinned);
241        [MethodImplAttribute(MethodImplOptions.InternalCall)]
242        internal static extern void InternalCompareExchange(IntPtr handle, Object value, Object oldValue, bool isPinned);
243        [MethodImplAttribute(MethodImplOptions.InternalCall)]
244  internal static extern IntPtr InternalAddrOfPinnedObject(IntPtr handle);
245        [MethodImplAttribute(MethodImplOptions.InternalCall)]
246  internal static extern void InternalCheckDomain(IntPtr handle);
247
248
249  // The actual integer handle value that the EE uses internally.
250  private IntPtr m_handle;
251    }

252}

253
254