1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.Generic; 6 using System.Diagnostics; 7 using System.Runtime; 8 using System.Runtime.InteropServices; 9 10 namespace System.Threading 11 { 12 internal static partial class WaitSubsystem 13 { 14 private static class HandleManager 15 { NewHandle(WaitableObject waitableObject)16 public static IntPtr NewHandle(WaitableObject waitableObject) 17 { 18 Debug.Assert(waitableObject != null); 19 20 IntPtr handle = RuntimeImports.RhHandleAlloc(waitableObject, GCHandleType.Normal); 21 22 // SafeWaitHandle treats -1 and 0 as invalid, and the handle should not be these values anyway 23 Debug.Assert(handle != IntPtr.Zero); 24 Debug.Assert(handle != new IntPtr(-1)); 25 return handle; 26 } 27 FromHandle(IntPtr handle)28 public static WaitableObject FromHandle(IntPtr handle) 29 { 30 if (handle == IntPtr.Zero || handle == new IntPtr(-1)) 31 { 32 WaitHandle.ThrowInvalidHandleException(); 33 } 34 35 // We don't know if any other handles are invalid, and this may crash or otherwise do bad things, that is by 36 // design, IntPtr is unsafe by nature. 37 return (WaitableObject)RuntimeImports.RhHandleGet(handle); 38 } 39 40 /// <summary> 41 /// Unlike on Windows, a handle may not be deleted more than once with this implementation 42 /// </summary> DeleteHandle(IntPtr handle)43 public static void DeleteHandle(IntPtr handle) 44 { 45 if (handle == IntPtr.Zero || handle == new IntPtr(-1)) 46 { 47 return; 48 } 49 50 // We don't know if any other handles are invalid, and this may crash or otherwise do bad things, that is by 51 // design, IntPtr is unsafe by nature. 52 ((WaitableObject)RuntimeImports.RhHandleGet(handle)).OnDeleteHandle(); 53 RuntimeImports.RhHandleFree(handle); 54 } 55 } 56 } 57 } 58