| File: System\Reflection\Internal\Utilities\PinnedObject.cs | Web Access |
| Project: src\runtime\src\libraries\System.Reflection.Metadata\src\System.Reflection.Metadata.csproj (System.Reflection.Metadata) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; namespace System.Reflection.Internal { internal sealed class PinnedObject : CriticalDisposableObject { // can't be read-only since GCHandle is a mutable struct private GCHandle _handle; // non-zero indicates a valid handle private int _isValid; public PinnedObject(object obj) { #if FEATURE_CER // Make sure the current thread isn't aborted in between allocating the handle and storing it. RuntimeHelpers.PrepareConstrainedRegions(); try { /* intentionally left blank */ } finally #endif { _handle = GCHandle.Alloc(obj, GCHandleType.Pinned); _isValid = 1; } } protected override void Release() { #if FEATURE_CER // Make sure the current thread isn't aborted in between zeroing the handle and freeing it. RuntimeHelpers.PrepareConstrainedRegions(); try { /* intentionally left blank */ } finally #endif { if (Interlocked.Exchange(ref _isValid, 0) != 0) { _handle.Free(); } } } public unsafe byte* Pointer => (byte*)_handle.AddrOfPinnedObject(); } }